JdbcTemplateTool Spring 出品的 JdbcTemplate 对于不想使用hibernate或者ibatis那样需要大量学习成本而且还想获得对象化的人来说是很好用的。但是 JdbcTemplate还是有很多不足之处或者说是缺点。比如你没法像hibernate那样直接传一个对象给它让他拆分成sql
JdbcTemplateTool

Spring 出品的 JdbcTemplate 对于不想使用hibernate或者ibatis那样需要大量学习成本而且还想获得对象化的人来说是很好用的。但是 JdbcTemplate还是有很多不足之处或者说是缺点。比如你没法像hibernate那样直接传一个对象给它让他拆分成sql并保存起来,当然这也是可以理解的,毕竟它并没有要求你去写 hbm.xml 文件所以无法知道你哪些字段要映射,哪些不要等等。又比如JdbcTemplate 可以帮忙把一个查询结果传化为一个对象列表,但是你需要查阅一些资料才知道要用 BeanPropertyRowMapper
。如果下次要用的时候又忘记了这个类,又要查一次或者翻以前的代码来看,其实完全可以提供一个方法直接传一个PO类进去自动创建
BeanPropertyRowMapper 。基于以上的一些不足之处,我建立了 JdbcTemplateTool 它有以下特性:
- 把查询结果转换为PO列表,不需要调用 BeanPropertyRowMapper
- 传一条统计sql比如 a select count(1) from table 可以直接返回一个数字作为结果,不需要自己实现中间步骤。
- 可以直接把一个PO类存到数据库
- 通过PO类和一个id可以获取到该对象
- 通过PO类可以直接update数据库记录
- 不需要实现 BatchPreparedStatementSetter, 就可以批量update
- 通过一个对PO对象删除对应的数据库记录
- 依然可以使用原始的 JdbcTemplate
目前只在mysql上测试.
Maven
依赖
1 2 3 4 5 | <dependency>
<groupId>org.crazycake</groupId>
<artifactId>jdbctemplatetool</artifactId>
<version>1.0.4-RELEASE</version>
</dependency>
|
登录后复制
快速开始
STEP
1. 创建一个maven项目
创建一个maven项目叫 testjtt. 添加 jdbctemplatetool 依赖到 pom.xml. 再添加以下依赖到 pom.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.2.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.19</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.2.RELEASE</version>
<scope>test</scope>
</dependency>
|
登录后复制
最好使用 1.6+ jdk. 我并没有在 1.5 下测试
STEP
2. 创建测试数据库
创建一个测试的数据库叫 jtt_test 创建一个用户 travis 不要分配密码.
赋予jtt_test的权限给 travis .
1 2 3 | CREATE USER 'travis' @ '%' IDENTIFIED BY '' ;
GRANT ALL ON jtt_test.* TO 'travis' @ '%' ;
flush privileges;
|
登录后复制
创建一张表 employee 插入一些测试数据.
1 2 3 4 5 6 7 8 9 10 11 12 13 | DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(300) NOT NULL,
`join_date` datetime NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `employee`(`id`,`name`,`join_date`,`age`) values (1, 'jack' , '2014-09-22 00:00:00' ,23),(2, 'ted' , '2014-08-30 00:00:00' ,25),(3, 'jim' , '2014-06-22 00:00:00' ,33);
|
登录后复制
STEP
3. 配置一下spring
在test文件夹下创建 resources 文件夹. 添加 resources 到
source folder 修改输出为 target/test-classes 创建 spring.xml 在
test/resources 里面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?xml version= "1.0" encoding= "UTF-8" ?>
<beans xmlns= "http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:
http:
<bean name= "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method= "close" >
<property name= "jdbcUrl" ><value>jdbc:mysql:
<property name= "driverClass" ><value>com.mysql.jdbc.Driver</value></property>
<property name= "user" ><value>travis</value></property>
<property name= "password" ><value></value></property>
</bean>
<bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate" >
<property name = "dataSource" ref= "dataSource" />
</bean>
<bean id= "jdbcTemplateTool" class = "org.crazycake.jdbcTemplateTool.JdbcTemplateTool" >
<property name = "jdbcTemplate" ref= "jdbcTemplate" />
</bean>
</beans>
|
登录后复制
STEP
4. 创建PO类
创建 Employee.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | import java.sql.Timestamp;
import javax.persistence.Id;
public class Employee {
private Integer id;
private String name;
private Timestamp joinDate;
private Integer age;
@Id
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Timestamp getJoinDate() {
return joinDate;
}
public void setJoinDate(Timestamp joinDate) {
this.joinDate = joinDate;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
|
登录后复制
STEP
5. 创建测试用例
创建 HelloJTTTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import org.crazycake.jdbcTemplateTool.JdbcTemplateTool;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
@ContextConfiguration(locations={ "classpath:spring.xml" })
public class HelloJTTTest extends AbstractJUnit4SpringContextTests{
@Test
public void testSave(){
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
Employee e = new Employee();
e.setId(4);
e.setName( "billy" );
Date now = new Date ();
e.setJoinDate( new Timestamp(now.getTime()));
e.setAge(33);
try {
jtt.save(e);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
|
登录后复制
STEP
6. 启动!
运行测试用例,等待绿色条。然后去数据库会看到多了一条记录 :
id |
name |
join_date |
age |
4 |
billy |
2014-09-24 22:51:20 |
33 |
高级教程
以下是各个方法的详细介绍
list
把查询结果转换为PO列表,不需要调用 BeanPropertyRowMapper 。
自动根据数据库的列将下划线转为驼峰命名规则映射类的属性.
1 2 3 4 5 6 7 8 | @Test
public void testList(){
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
List<Employee> es = jtt.list( "select * from employee where age < ? order by id desc" , new Object[]{30}, Employee. class );
assertThat( new Integer(es.size()),is(2));
assertThat(es.get(1).getName(),is( "jack" ));
}
|
登录后复制
count
传一条统计sql比如 a select
count(1) from table 可以直接返回一个数字作为结果,不需要自己实现中间步骤。
1 2 3 4 5 6 7 | @Test
public void testCount() throws IOException, SQLException {
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
int total = jtt. count ( "select count(1) from employee" , null);
assertThat(total,is(4));
}
|
登录后复制
save
可以直接把一个PO类存到数据库。如果你不想把某个列映射为数据库字段可以使用 @Trasient 注解在getter上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public class Student {
private Integer id;
private String name;
private String nothing;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Transient
public String getNothing() {
return nothing;
}
public void setNothing(String nothing) {
this.nothing = nothing;
}
}
|
登录后复制
这个字段会被跳过
1 2 3 4 5 6 7 8 9 10 | @Test
public void testSave() throws Exception {
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
Student s = new Student();
s.setName( "michael" );
s.setNothing( "nothing" );
jtt.save(s);
}
|
登录后复制
get
通过PO类和一个id可以获取到该对象。但是前提是需要在主键的getter上标上 @Id 注解
1 2 3 4 | @Id
public Integer getId() {
return id;
}
|
登录后复制
例子
1 2 3 4 5 6 7 8 | @Test
public void testGet() throws NoIdAnnotationFoundException, NoColumnAnnotationFoundException, IOException, SQLException {
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
Employee e = jtt.get(Employee. class , 3);
assertThat(e.getName(),is( "jim" ));
}
|
登录后复制
update
自动根据PO类更新数据库. 记得增加 @Id .
1 2 3 4 5 6 7 8 9 | @Test
public void testUpdate() throws Exception {
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
Employee e = jtt.get(Employee. class , 1);
e.setAge(23);
jtt.update(e);
}
|
登录后复制
batchUpdate
批量更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Test
public void testBatchUpdate() throws SQLException, IOException {
build();
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
List<Object[]> params = new ArrayList<Object[]>();
Object[] p1 = new Object[]{23, "jack" };
params.add(p1);
Object[] p2 = new Object[]{29, "tim" };
params.add(p2);
jtt.batchUpdate( "update employee set age = ? where name = ?" , params);
}
|
登录后复制
delete
删除数据库对象
1 2 3 4 5 6 7 | @Test
public void testDelete() throws Exception {
JdbcTemplateTool jtt = super.applicationContext.getBean( "jdbcTemplateTool" ,JdbcTemplateTool. class );
Employee e = new Employee();
e.setId(1);
jtt. delete (e);
}
|
登录后复制
getJdbcTemplate
你依然可以使用原始的 JdbcTemplate. 调用 JdbcTemplateTool.getJdbcTemplate() to
getJdbcTemplate 就可以了。