JdbcTemplate的使用

Spring为了各种支持的持久化技术,都提供了简单操作的模版和回调。

JdbcTemplate 简化 JDBC 操作
HibernateTemplate 简化 Hibernate 操作

下面列出几种熟悉的

Spring JDBC是Spring提供的持久层技术

简化JDBC API开发 ,使用上和Apache公司的DBUtils框架非常类似

 

1、使用JdbcTemplate快速入门

导入必要jar包到工程目录
导入Spring核心开发包到创建工程
  spring-beans-3.2.0.RELEASE.jar
  spring-context-3.2.0.RELEASE.jar
  spring-core-3.2.0.RELEASE.jar
  spring-expression-3.2.0.RELEASE.jar
还需要下载commons-logging日志包
  commons-logging-1.1.1.jar
集成log4j 导入log4j jar包
  com.springsource.org.apache.log4j-1.2.15.jar

  src下面:log4j.properties
导入JDBC模板开发包
  spring-jdbc-3.2.0.RELEASE.jar
  spring-tx-3.2.0.RELEASE.jar
数据库驱动

 

复制代码

 1     @Test
 2     // 无配置文件测试
 3     public void demo1() {
 4         // Spring 内置连接池
 5         DriverManagerDataSource dataSource = new DriverManagerDataSource();
 6         // 需要 jdbc 四个参数
 7         dataSource.setDriverClassName("com.mysql.jdbc.Driver");
 8         dataSource.setUrl("jdbc:mysql:///spring3day2");
 9         dataSource.setUsername("root");
10         dataSource.setPassword("abc");
11 
12         JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
13 
14         // 建个表
15         jdbcTemplate.execute("create table abcd(id int , name varchar(20))");
16     }

复制代码

2、在实际开发中通过Spring 配置文件来配置 JdbcTemplate

配置三种数据库连接池

1)Spring数据源实现类DriverManagerDataSource

复制代码

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="
 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 8 
 9 <!-- Spring内置连接池 -->
10 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
11     <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
12     <property name="url" value="jdbc:mysql:///spring"></property>
13     <property name="username" value="root"></property>
14     <property name="password" value="root"></property>
15 </bean>
16 </beans>

复制代码

 

2)DBCP 数据源 BasicDataSource
 在原有jar上加入           com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
                    com.springsource.org.apache.commons.pool-1.5.3.jar

复制代码

 1    配置dbcp 连接池
 2    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
 3         <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
 4         <property name="url" value="jdbc:mysql:///spring3day2"></property>
 5         <property name="username" value="root"></property>
 6         <property name="password" value="abc"></property>
 7         <property name="initialSize" value="1" />
 8         <property name="maxActive" value="30" />
 9         <property name="maxIdle" value="30" />
10         <property name="minIdle" value="3" />
11         <property name="removeAbandoned" value="true" />
12         <property name="removeAbandonedTimeout" value="3600" />
13         <property name="testWhileIdle" value="true" />
14         <property name="validationQuery" value="select 1" />
15         <property name="validationQueryTimeout" value="1" />
16         <property name="timeBetweenEvictionRunsMillis" value="60000" />
17         <property name="numTestsPerEvictionRun" value="30" />
18     </bean>    

复制代码

 

 

3)C3P0 数据源  ComboPooledDataSource

在原有jar上加入    com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

 

复制代码

1     <!-- 配置c3p0 连接池 -->
2     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
3         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
4         <property name="jdbcUrl" value="jdbc:mysql:///spring3"></property>
5         <property name="user" value="root"></property>
6         <property name="password" value="root"></property>
7     </bean>

复制代码

 

 

3、 使Spring 配置文件引用外部 properties 属性文件 (配置jdbc连接参数)

<context:property-placeholder> 引入外部 properties 属性文件

复制代码

 1 jdbc.properties
 2         jdbc.driver=com.mysql.jdbc.Driver
 3         jdbc.url=jdbc:mysql:///spring
 4         jdbc.username=root
 5         jdbc.password=root
 6 
 7 
 8 applicationContext.xml
 9     <!-- 引入外部 properties 文件 -->
10     
11     <context:property-placeholder location="classpath:jdbc.properties"/>
12     
13     <!-- 配置c3p0 连接池 -->
14     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
15         <property name="driverClass" value="${jdbc.driver}"></property>
16         <property name="jdbcUrl" value="${jdbc.url}"></property>
17         <property name="user" value="${jdbc.username}"></property>
18         <property name="password" value="${jdbc.password}"></property>
19     </bean>

复制代码

 

4、测试

复制代码

 1 在applicationContext.xml中注册连接池
 2     <!-- 将连接池注入 jdbcTemplate -->
 3     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
 4         <property name="dataSource" ref="dataSource"></property>
 5     </bean>
 6 
 7 
 8 public class JdbcTemplateTest {
 9     @Test
10     // 使用配置文件 测试
11     public void demo2() {
12         ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
13                 "applicationContext.xml");
14         JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext
15                 .getBean("jdbcTemplate");
16 
17         jdbcTemplate.execute("create table abcd(id int , name varchar(20))");
18     }
19 }

复制代码

5、jdbcTemplate API 分析
Spring为了 在DAO 中可以方便注入 Template 模板操作类, 提供了一组 DaoSupport 支持类

JdbcDaoSupport.java

复制代码

 1 package org.springframework.jdbc.core.support;
 2 
 3 import java.sql.Connection;
 4 import javax.sql.DataSource;
 5 import org.springframework.dao.support.DaoSupport;
 6 import org.springframework.jdbc.CannotGetJdbcConnectionException;
 7 import org.springframework.jdbc.core.JdbcTemplate;
 8 import org.springframework.jdbc.datasource.DataSourceUtils;
 9 import org.springframework.jdbc.support.SQLExceptionTranslator;
10 
11 public abstract class JdbcDaoSupport extends DaoSupport
12 {
13 
14     public JdbcDaoSupport()
15     {
16     }
17 
18     public final void setDataSource(DataSource dataSource)
19     {
20         if(jdbcTemplate == null || dataSource != jdbcTemplate.getDataSource())
21         {
22             jdbcTemplate = createJdbcTemplate(dataSource);
23             initTemplateConfig();
24         }
25     }
26 
27     protected JdbcTemplate createJdbcTemplate(DataSource dataSource)
28     {
29         return new JdbcTemplate(dataSource);
30     }
31 
32     public final DataSource getDataSource()
33     {
34         return jdbcTemplate == null ? null : jdbcTemplate.getDataSource();
35     }
36 
37     public final void setJdbcTemplate(JdbcTemplate jdbcTemplate)
38     {
39         this.jdbcTemplate = jdbcTemplate;
40         initTemplateConfig();
41     }
42 
43     public final JdbcTemplate getJdbcTemplate()
44     {
45         return jdbcTemplate;
46     }
47 
48     protected void initTemplateConfig()
49     {
50     }
51 
52     protected void checkDaoConfig()
53     {
54         if(jdbcTemplate == null)
55             throw new IllegalArgumentException("'dataSource' or 'jdbcTemplate' is required");
56         else
57             return;
58     }
59 
60     protected final SQLExceptionTranslator getExceptionTranslator()
61     {
62         return getJdbcTemplate().getExceptionTranslator();
63     }
64 
65     protected final Connection getConnection()
66         throws CannotGetJdbcConnectionException
67     {
68         return DataSourceUtils.getConnection(getDataSource());
69     }
70 
71     protected final void releaseConnection(Connection con)
72     {
73         DataSourceUtils.releaseConnection(con, getDataSource());
74     }
75 
76     private JdbcTemplate jdbcTemplate;
77 }

复制代码

 

* 比如 DAO extends JdbcDaoSupport 注入 JdbcTemplate
* 比如 DAO extends HibernateDaoSupport 注入 HibernateTemplate

如果要实现DAO 增加、修改 、删除 JdbcTemplate.update(sql,Object... args)

使用DAO 查询 
    1) 简单查询 
        queryForInt
        queryForObject
    // 根据id 查询 name
    public String findNameById(int id) {
        String sql = "select name from person where id = ?";
        return this.getJdbcTemplate().queryForObject(sql, String.class, id);
    }

    // 查询总记录数
    public int findByTotalCount() {
        String sql = "select count(*) from person";
        return this.getJdbcTemplate().queryForInt(sql);
    }
    
    2) 返回对象和对象集合的查询
        关键点,提供每条数据记录 如何 封装为对象 RowMapper的实现 
        private class MyPersonRowMapper implements RowMapper<Person> {
            @Override
            // resultset 查询结果集
            // i 行号
            public Person mapRow(ResultSet rs, int i) throws SQLException {
                // 要将 当前结果集 指定行 数据 封装到 Person 对象
                Person person = new Person();
                person.setId(rs.getInt("id"));
                person.setName(rs.getString("name"));
                person.setCity(rs.getString("city"));
                return person;
            }
        }

 

使用jdbcTemplate 实现DAO ,完成CURD 功能

 

1、创建数据库表

1 create table person(
2    id int primary key auto_increment,
3    name varchar(20),
4    city varchar(40)
5 );

2、Person.java

复制代码

 1 package cn.itcast.domain;
 2 
 3 public class Person {
 4     private int id;
 5     private String name;
 6     private String city;
 7 
 8     public int getId() {
 9         return id;
10     }
11 
12     public void setId(int id) {
13         this.id = id;
14     }
15 
16     public String getName() {
17         return name;
18     }
19 
20     public void setName(String name) {
21         this.name = name;
22     }
23 
24     public String getCity() {
25         return city;
26     }
27 
28     public void setCity(String city) {
29         this.city = city;
30     }
31 
32     @Override
33     public String toString() {
34         return "Person [id=" + id + ", name=" + name + ", city=" + city + "]";
35     }
36 
37 }

复制代码

 

3、PersonDAO.java

复制代码

 1 package cn.itcast.dao;
 2 
 3 import java.sql.ResultSet;
 4 import java.sql.SQLException;
 5 import java.util.List;
 6 
 7 import org.springframework.jdbc.core.RowMapper;
 8 import org.springframework.jdbc.core.support.JdbcDaoSupport;
 9 
10 import cn.itcast.domain.Person;
11 
12 /**
13  * 实现 Person表 增删改查 ,使用JdbcTemplate
14  * 
15  * @author seawind
16  * 
17  */
18 public class PersonDAO extends JdbcDaoSupport {
19     // 需要向PersonDAO 注入 JdbcTemplate
20 
21     public Person findById(int id) {
22         String sql = "select * from person where id = ?";
23         return this.getJdbcTemplate().queryForObject(sql,
24                 new MyPersonRowMapper(), id);
25     }
26 
27     public List<Person> findAll() {
28         String sql = "select * from person";
29         return this.getJdbcTemplate().query(sql, new MyPersonRowMapper());
30     }
31 
32     // 必须提供手动封装类,完成每条记录 到 Person 对象封装
33     private class MyPersonRowMapper implements RowMapper<Person> {
34         @Override
35         // resultset 查询结果集
36         // i 行号
37         public Person mapRow(ResultSet rs, int i) throws SQLException {
38             // 要将 当前结果集 指定行 数据 封装到 Person 对象
39             Person person = new Person();
40             person.setId(rs.getInt("id"));
41             person.setName(rs.getString("name"));
42             person.setCity(rs.getString("city"));
43             return person;
44         }
45     }
46 
47     // 根据id 查询 name
48     public String findNameById(int id) {
49         String sql = "select name from person where id = ?";
50         return this.getJdbcTemplate().queryForObject(sql, String.class, id);
51     }
52 
53     // 查询总记录数
54     public int findByTotalCount() {
55         String sql = "select count(*) from person";
56         return this.getJdbcTemplate().queryForInt(sql);
57     }
58 
59     public void save(Person person) {
60         String sql = "insert into person values(null,?,?)";
61         this.getJdbcTemplate().update(sql, person.getName(), person.getCity());
62     }
63 
64     public void update(Person person) {
65         String sql = "update person set name=? , city=? where id = ?";
66         this.getJdbcTemplate().update(sql, person.getName(), person.getCity(),
67                 person.getId());
68     }
69 
70     public void delete(Person person) {
71         String sql = "delete from person where id = ?";
72         this.getJdbcTemplate().update(sql, person.getId());
73     }
74 }

复制代码

 

4、PersonDAOTest.java

复制代码

 1 package cn.itcast.test;
 2 
 3 import java.util.List;
 4 
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.test.context.ContextConfiguration;
 9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
10 
11 import cn.itcast.dao.PersonDAO;
12 import cn.itcast.domain.Person;
13 
14 /**
15  * 使用Spring 测试
16  * 
17  * @author seawind
18  * 
19  */
20 @RunWith(SpringJUnit4ClassRunner.class)
21 @ContextConfiguration(locations = "classpath:applicationContext.xml")
22 public class PersonDAOTest {
23     @Autowired//可以完成自动装配 无需提供setter方法
24     private PersonDAO personDAO;
25 
26     // 测试添加
27     @Test
28     public void testSave() {
29         Person person = new Person();
30         person.setName("小明");
31         person.setCity("北京");
32 
33         personDAO.save(person);
34     }
35 
36     @Test
37     // 测试修改
38     public void testUpdate() {
39         Person person = new Person();
40         person.setId(1);
41         person.setName("小明");
42         person.setCity("上海");
43 
44         personDAO.update(person);
45     }
46 
47     @Test
48     // 测试删除
49     public void testDelete() {
50         Person person = new Person();
51         person.setId(1);
52 
53         personDAO.delete(person);
54     }
55 
56     @Test
57     // 测试简单查询
58     public void testSimpleSelect() {
59         String name = personDAO.findNameById(2);
60         System.out.println(name);
61         System.out.println(personDAO.findByTotalCount());
62     }
63 
64     @Test
65     // 根据id 查询
66     public void testFindById() {
67         Person person = personDAO.findById(2);
68         System.out.println(person);
69     }
70 
71     @Test
72     // 查询所有数据
73     public void testFindAll() {
74         List<Person> persons = personDAO.findAll();
75         System.out.println(persons);
76     }
77 
78 }

复制代码

 

5、applicationContext.xml

复制代码

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="
 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 8     <!-- 配置数据库连接池 -->
 9     <!-- 引入外部 properties 文件 -->
10     
11     <context:property-placeholder location="classpath:jdbc.properties"/>
12     
13     <!-- 配置c3p0 连接池 -->
14     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
15         <property name="driverClass" value="${jdbc.driver}"></property>
16         <property name="jdbcUrl" value="${jdbc.url}"></property>
17         <property name="user" value="${jdbc.username}"></property>
18         <property name="password" value="${jdbc.password}"></property>
19     </bean>
20         
21     <!-- 将连接池注入 jdbcTemplate -->
22     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
23         <property name="dataSource" ref="dataSource"></property>
24     </bean>
25     
26     <!-- 配置DAO -->
27     <bean id="personDAO" class="cn.itcast.dao.PersonDAO">
28         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
29     </bean>
30 </beans>

复制代码

 

 

 

参考推荐

Spring MVC 三种数据库连接池配置