JdbcTemplate 简介
· 为了使 JDBC 更加易于使用, Spring在 JDBC API上定义了一个抽象层,以此建立一个 JDBC存取框架.
· 作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的JDBC 操作提供模板方法.每个模板方法都能控制整个过程,并允许覆盖过程中的特定任务.通过这种方式,可以在尽可能保留灵活性的情况下,将数据库存取的工作量降到最低.
使用JdbcTemplate
①.加入依赖或jar
[html] view plain copy
1. <dependencies>
2. <dependency>
3. <groupId>org.springframework</groupId>
4. <artifactId>spring-context</artifactId>
5. <version>4.3.2.RELEASE</version>
6. </dependency>
7.
8. <dependency>
9. <groupId>mysql</groupId>
10. <artifactId>mysql-connector-java</artifactId>
11. <version>5.1.28</version>
12. </dependency>
13.
14. <dependency>
15. <groupId>c3p0</groupId>
16. <artifactId>c3p0</artifactId>
17. <version>0.9.1.2</version>
18. </dependency>
19.
20. <dependency>
21. <groupId>junit</groupId>
22. <artifactId>junit</artifactId>
23. <version>4.12</version>
24. </dependency>
25.
26. <dependency>
27. <groupId>org.springframework</groupId>
28. <artifactId>spring-jdbc</artifactId>
29. <version>4.3.4.RELEASE</version>
30. </dependency>
31. </dependencies>
②.数据库相关配置
dept表:id dept_name
emp表:id name email deptid
并创建相关实体
db.properties
[html] view plain copy
1. jdbc.user=root
2. jdbc.password=123456
3. jdbc.driverClass=com.mysql.jdbc.Driver
4. jdbc.jdbcUrl=jdbc:mysql:///test
5.
6. jdbc.initPoolSize=5
7. jdbc.maxPoolSize=10
③.配置c3p0数据源
[html] view plain copy
1. <!-- 导入资源文件 -->
2. <context:property-placeholder location="classpath:db.properties" />
3.
4. <!-- 配置 C3P0 数据源 -->
5. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
6. <property name="user" value="${jdbc.user}"></property>
7. <property name="password" value="${jdbc.password}"></property>
8. <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
9. <property name="driverClass" value="${jdbc.driverClass}"></property>
10.
11. <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
12. <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
13. </bean>
④.配置JdbcTemplate
[html] view plain copy
1. <!-- 配置 Spirng 的 JdbcTemplate -->
2. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
3. <property name="dataSource" ref="dataSource"></property>
4. </bean>
⑤.测试JdbcTemplate
[java] view plain copy
1. package com.xyc.spring.jdbc;
2.
3. import java.sql.SQLException;
4.
5. import javax.sql.DataSource;
6.
7. import org.junit.Test;
8. import org.springframework.context.ApplicationContext;
9. import org.springframework.context.support.ClassPathXmlApplicationContext;
10. import org.springframework.jdbc.core.JdbcTemplate;
11.
12. /**
13. *
14. * @ClassName: SpringJDBCTest
15. * @Description:测试 JdbcTemplate
16. * @author: xyc
17. * @date: 2016年12月25日 下午5:57:20
18. *
19. */
20. public class SpringJDBCTest {
21.
22. private ApplicationContext context;
23.
24. private JdbcTemplate jdbcTemplate;
25.
26. {
27. context = new ClassPathXmlApplicationContext("applicationContext.xml");
28. jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");
29. }
30.
31. /**
32. *
33. * @Title: testUpdate
34. * @Description: 执行 INSERT, UPDATE, DELETE
35. * @param:
36. * @return: void
37. * @throws
38. */
39. @Test
40. public void testUpdate() {
41. // String sql = "UPDATE emp SET name = ? WHERE id = ?";
42. // jdbcTemplate.update(sql, "Jack", 5);
43.
44. // String sql = "delete from emp where id = ?";
45. // jdbcTemplate.update(sql, 6);
46.
47. String sql = "insert into emp(name,email,dept_id) value(?,?,?)";
48. jdbcTemplate.update(sql, "HH", "hh@zto.com", 1);
49. }
50.
51. /**
52. *
53. * @Title: getConnection
54. * @Description: 测试连接
55. * @param: @throws SQLException
56. * @return: void
57. * @throws
58. */
59. @Test
60. public void getConnection() throws SQLException {
61. DataSource dataSource = (DataSource) context.getBean("dataSource");
62. System.out.println(dataSource.getConnection());
63. }
64. }
JdbcTemplate实例
执行批量更新:
[java] view plain copy
1. /**
2. *
3. * @Title: testBatchUpdate
4. * @Description: 执行批量更新: 批量的 INSERT, UPDATE, DELETE 最后一个参数是 Object[] 的 List 类型: 因为修改一条记录需要一个
5. * Object 的数组,那么多条不就需要多个 Object 的数组吗
6. * @param:
7. * @return: void
8. * @throws
9. */
10. @Test
11. public void testBatchUpdate() {
12. String sql = "INSERT INTO emp(name, email, dept_id) VALUES(?,?,?)";
13.
14. List<Object[]> batchArgs = new ArrayList<>();
15.
16. batchArgs.add(new Object[] { "AA", "aa@zto.com", 1 });
17. batchArgs.add(new Object[] { "BB", "bb@zto.com", 2 });
18. batchArgs.add(new Object[] { "CC", "cc@zto.com", 3 });
19. batchArgs.add(new Object[] { "DD", "dd@zto.com", 3 });
20. batchArgs.add(new Object[] { "EE", "ee@zto.com", 2 });
21.
22. jdbcTemplate.batchUpdate(sql, batchArgs);
23. }
获取一条记录:
[java] view plain copy
1. /**
2. *
3. * @Title: testQueryForObject
4. * @Description: 从数据库中获取一条记录, 实际得到对应的一个对象 注意不是调用 queryForObject(String sql, Class<Employee>
5. * requiredType,Object... args) 方法! 而需要调用 queryForObject(String sql,
6. * RowMapper<Employee> rowMapper, Object...args)
7. * 1. 其中的 RowMapper 指定如何去映射结果集的行,常用的实现类为 BeanPropertyRowMapper
8. * 2. 使用 SQL中列的别名完成列名和类的属性名的映射. 例如 last_name lastName
9. * 3. 不支持级联属性. JdbcTemplate 到底是一个 JDBC 的小工具, 而不是 ORM框架
10. * @param:
11. * @return: void
12. * @throws
13. */
14. @Test
15. public void testQueryForObject() {
16. String sql = "SELECT id, name , email, dept_id FROM emp WHERE id = ?";
17. RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
18. Emp employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);
19.
20. System.out.println(employee);
21. }
查询实体类的集合:
[java] view plain copy
1. /**
2. *
3. * @Title: testQueryForList
4. * @Description: 查询实体类的集合 注意调用的不是 queryForList 方法
5. * @param:
6. * @return: void
7. * @throws
8. */
9. @Test
10. public void testQueryForList() {
11. String sql = "SELECT id, name , email FROM emp WHERE id > ?";
12. RowMapper<Emp> rowMapper = new BeanPropertyRowMapper<>(Emp.class);
13. List<Emp> employees = jdbcTemplate.query(sql, rowMapper, 5);
14.
15. System.out.println(employees);
16. }
获取单个列的值
[java] view plain copy
1. /**
2. *
3. * @Title: testQueryForObject2
4. * @Description: 获取单个列的值, 或做统计查询 使用 queryForObject(String sql, Class<Long> requiredType)
5. * @param:
6. * @return: void
7. * @throws
8. */
9. @Test
10. public void testQueryForObject2() {
11. String sql = "SELECT count(id) FROM emp";
12. long count = jdbcTemplate.queryForObject(sql, Long.class);
13.
14. System.out.println(count);
15. }
JdbcDaoSupport
Spring JDBC 框架还提供了一个 JdbcDaoSupport类来简化 DAO实现. 该类声明了 jdbcTemplate属性
[java] view plain copy
1. /**
2. *
3. * @ClassName: DeptDao
4. * @Description:扩展 JdbcDaoSupport 不推荐使用 JdbcDaoSupport, 而推荐直接使用 JdbcTempate 作为 Dao 类的成员变量
5. * @author: xyc
6. * @date: 2016年12月25日 下午5:16:41
7. *
8. */
9. @Repository("deptDAO")
10. public class DeptDAO extends JdbcDaoSupport {
11.
12. <span style="color:#ff0000;">@Autowired
13. public void setDataSource2(DataSource dataSource) {
14. setDataSource(dataSource);
15. }</span>
16.
17. public Dept get(Integer id) {
18. String sql = "SELECT id, dept_name FROM dept WHERE id = ?";
19. RowMapper<Dept> rowMapper = new BeanPropertyRowMapper<>(Dept.class);
20. return getJdbcTemplate().queryForObject(sql, rowMapper, id);
21. }
22.
23. }
测试:
[java] view plain copy
1. package com.xyc.spring.jdbc;
2.
3. import org.junit.Test;
4. import org.springframework.context.ApplicationContext;
5. import org.springframework.context.support.ClassPathXmlApplicationContext;
6.
7. public class SpringJDBCTest {
8.
9. private ApplicationContext context;
10.
11. private DeptDAO deptDAO;
12.
13. {
14. context = new ClassPathXmlApplicationContext("applicationContext.xml");
15. deptDAO = (DeptDAO) context.getBean("deptDAO");
16. }
17.
18. /**
19. *
20. * @Title: testDepartmentDao
21. * @Description: 测试实现JdbcDaoSupport接口的使用
22. * @param:
23. * @return: void
24. * @throws
25. */
26. @Test
27. public void testDepartmentDao() {
28. System.out.println(deptDAO.get(2));
29. }
30. }
在 JDBC模板中使用具名参数
配置NamedParameterJdbcTemplate
[html] view plain copy
1. <!-- 配置 NamedParameterJdbcTemplate, 该对象可以使用具名参数, 其没有无参数的构造器, 所以必须为其构造器指定参数 -->
2. <bean id="namedParameter"
3. class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
4. <constructor-arg ref="dataSource"></constructor-arg>
5. </bean>
测试:
[java] view plain copy
1. package com.xyc.spring.jdbc;
2.
3. import java.util.HashMap;
4. import java.util.Map;
5.
6. import org.junit.Test;
7. import org.springframework.context.ApplicationContext;
8. import org.springframework.context.support.ClassPathXmlApplicationContext;
9. import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
10. import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
11. import org.springframework.jdbc.core.namedparam.SqlParameterSource;
12.
13. public class SpringJDBCTest {
14.
15. private ApplicationContext context;
16.
17. private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
18.
19. {
20. context = new ClassPathXmlApplicationContext("applicationContext.xml");
21. namedParameterJdbcTemplate = context.getBean(NamedParameterJdbcTemplate.class);
22. }
23.
24. /**
25. * 使用具名参数时, 可以使用 update(String sql, SqlParameterSource paramSource) 方法进行更新操作 1. SQL
26. * 语句中的参数名和类的属性一致! 2. 使用 SqlParameterSource 的 BeanPropertySqlParameterSource 实现类作为参数.
27. */
28. @Test
29. public void testNamedParameterJdbcTemplate2() {
30. String sql = "INSERT INTO emp(name, email, dept_id) " + "VALUES(:name,:email,:dept_id)";
31.
32. Emp employee = new Emp();
33. employee.setName("XYC");
34. employee.setEmail("xyc@sina.com");
35. employee.setDept_id(3);
36.
37. SqlParameterSource paramSource = new BeanPropertySqlParameterSource(employee);
38. namedParameterJdbcTemplate.update(sql, paramSource);
39. }
40.
41. /**
42. * 可以为参数起名字. 1. 好处: 若有多个参数, 则不用再去对应位置, 直接对应参数名, 便于维护 2. 缺点: 较为麻烦.
43. */
44. @Test
45. public void testNamedParameterJdbcTemplate() {
46. String sql = "INSERT INTO emp(name, email, dept_id) VALUES(:ln,:email,:deptid)";
47.
48. Map<String, Object> paramMap = new HashMap<>();
49. paramMap.put("ln", "YY");
50. paramMap.put("email", "yy@zto.com");
51. paramMap.put("deptid", 2);
52.
53. namedParameterJdbcTemplate.update(sql, paramMap);
54. }
55.
56. }