Spring4笔记8--Spring与JDBC模板(IoC应用的例子)

Spring 与 JDBC模板:

  为了避免直接使用 JDBC 而带来的复杂且冗长的代码,Spring 提供了一个强有力的模板类---JdbcTemplate 来简化 JDBC 操作。并且,数据源 DataSource 对象与模板 JdbcTemplate 对象均可通过 Bean 的形式定义在配置文件中,充分发挥了依赖注入的威力

  因此,对于 JDBC 模板的使用,是 IoC 的应用,是将数据源 DataSource 对象和 JDBC 模板对象注入给了 Dao 层的实现类。

  代码详解:

    (1)定义实体类 User

 1 package com.tongji.beans;
 2 
 3 public class Student {
 4     private Integer id;
 5     private String name;
 6     private int age;
 7     
 8     public Integer getId() {
 9         return id;
10     }
11 
12     public void setId(Integer 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 int getAge() {
25         return age;
26     }
27 
28     public void setAge(int age) {
29         this.age = age;
30     }
31 
32     public Student() {
33         super();
34     }
35 
36     public Student(String name, int age) {
37         super();
38         this.name = name;
39         this.age = age;
40     }
41 
42     @Override
43     public String toString() {
44         return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
45     }
46     
47 }

    

    (2)定义数据库及表

    

    (3)定义IStudentDao接口:

 1 package com.tongji.dao;
 2 
 3 import java.util.List;
 4 
 5 import com.tongji.beans.Student;
 6 
 7 public interface IStudentDao {
 8     void insertStudent(Student student);
 9     void deleteStudent(int id);
10     void updateStudent(Student student);
11     
12     String selectStudentNameById(int id);
13     List<String> selectStudentNames();
14     
15     Student selectStudentById(int id);
16     List<Student> selectStudents();
17 }

    

    (4)定义IStudentDaoImpl实现类:

 1 package com.tongji.dao;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.jdbc.core.support.JdbcDaoSupport;
 6 
 7 import com.tongji.beans.Student;
 8 
 9 public class StudentDaoImpl extends JdbcDaoSupport implements IStudentDao {
10 
11     //JDBC模板对增删改的实现都是通过update方法
12     @Override
13     public void insertStudent(Student student) {
14         String sql = "insert into student(name,age) value(?,?)";
15         this.getJdbcTemplate().update(sql, student.getName(), student.getAge());
16     }
17 
18     @Override
19     public void deleteStudent(int id) {
20         String sql = "delete from student where id = ?";
21         this.getJdbcTemplate().update(sql, id);
22     }
23 
24     @Override
25     public void updateStudent(Student student) {
26         String sql = "update student set name = ?, age = ? where id = ?";
27         this.getJdbcTemplate().update(sql, student.getName(), student.getAge(), student.getId());
28     }
29 
30     @Override
31     public String selectStudentNameById(int id) {
32         String sql = "select name from student where id = ?";
33         return this.getJdbcTemplate().queryForObject(sql, String.class, id);
34     }
35 
36     @Override
37     public List<String> selectStudentNames() {
38         String sql = "select name from student";
39         return this.getJdbcTemplate().queryForList(sql, String.class);
40     }
41 
42     @Override
43     public Student selectStudentById(int id) {
44         String sql = "select * from student where id = ?";
45         return (Student) this.getJdbcTemplate().queryForObject(sql, new StudentRowMapper(), id);
46     }
47 
48     @Override
49     public List<Student> selectStudents() {
50         String sql = "select * from student";
51         return this.getJdbcTemplate().query(sql, new StudentRowMapper());
52     }
53 
54 }

  对Dao实现类的解释:

  (1) 继承JdbcDaoSupport 类的作用:

    Dao 实现类继承 JdbcDaoSupport 类,JdbcDaoSupport 类中有一个属性 JdbcTemplate,用于接收 JDBC 模板。所以 Dao 实现类继承了 JdbcDaoSupport 类后,也就具有了 JDBC 模板属性。在配置文件中,只要将模板对象注入即可。   
    再仔细查看 JdbcDaoSupport 类,发现其有一个 dataSource 属性,查看 setDataSource()方法体可知,若 JDBC 模板为 null,则会自动创建一个模板对象。

    所以,在 Spring 配置文件中,对于 JDBC 模板对象的配置完全可以省去,而是在 Dao 实现类中直接注入数据源对象。这样会让系统自动创建 JDBC 模板对象。

    

    

  (2) JdbcTemplate 类对数据库的操作方法:

    JdbcTemplate 类中提供了对 DB 进行修改、查询的方法。Dao 实现类使用继承自JdbcDaoSupport 的 getTemplate()方法,可以获取到 JDBC 模板对象。

    (1)对 DB 的增、删、改都是通过 update()方法实现的。该方法常用的重载方法有两个:

      public int update ( String sql)
      public int update ( String sql, Object… args)  
    第 1 个参数为要执行的 sql 语句,第 2 个参数为要执行的 sql 语句中所包含的动态参数。其返回值为所影响记录的条数。一般不用。

    (2)JDBC 模板的查询结果均是以对象的形式返回。根据返回对象类型的不同,可以将查询分为两类:简单对象查询,与自定义对象查询。  
      简单对象查询:查询结果为 String、Integer 等简单对象类型,或该类型做为元素的集合类型,如 List<String>等。  
      自定义对象查询:查询结果为自定义类型,如 User 等,或该类型做为元素的集合类型,如 List<User>等。
        (1)简单对象查询
        常用的简单对象查询方法有:查询结果为单个对象的 queryForObject()与查询结果为 List的 queryForList()。  
          pubic T queryForObject (String sql, Class<T> type, Object... args)
          pubic List<T> queryForList (String sql, Class<T> type, Object... args) 

      (2)自定义对象查询
        常用的自定义对象查询方法有:查询结果为单个对象的 queryForObject()与查询结果为List 的 query()。  
          pubic T queryForObject (String sql, RowMapper<T> m , Object... args)
          pubic List<T> query (String sql, RowMapper<T > m, Object... args)  
        注意,RowMapper 为记录映射接口,用于将查询结果集中每一条记录包装为指定对象。该接口中有一个方法需要实现:
          public Object mapRow(ResultSet rs, int rowNum)  
        参数 rowNum 表示总的结果集中当前行的行号,但参数 rs 并不表示总的结果集,而是表示 rowNum 所代表的当前行的记录所定义的结果集,仅仅是当前行的结果。  
        一般,该方法体中就是实现将查询结果中当前行的数据包装为一个指定对象

        自定义的RowMapper实现类:

package com.tongji.dao;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import com.tongji.beans.Student;

//将数据库中的一行记录包装为一个对象
public class StudentRowMapper implements RowMapper<Student> {

    //rs:查询总结果集中,当前遍历的这一行
    //rowNum:当前遍历的行号
    @Override
    public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
        Student student = new Student();
        //从rs中读取数据,并将其包装为student对象
        student.setId(rs.getInt("id"));
        student.setName(rs.getString("name"));
        student.setAge(rs.getInt("age"));
        return student;
    }

}

 

    (5)定义IStudentService接口:

 1 package com.tongji.service;
 2 
 3 import java.util.List;
 4 
 5 import com.tongji.beans.Student;
 6 
 7 public interface IStudentService {
 8     void addStudent(Student student);
 9     void removeStudent(int id);
10     void modifyStudent(Student student);
11     
12     String findStudentNameById(int id);
13     List<String> findStudentNames();
14     
15     Student findStudentById(int id);
16     List<Student> findStudents();
17 }

 

    (6)定义IStudentServiceImpl实现类:

 1 package com.tongji.service;
 2 
 3 import java.util.List;
 4 
 5 import com.tongji.beans.Student;
 6 import com.tongji.dao.IStudentDao;
 7 
 8 public class StudentServiceImpl implements IStudentService {
 9     private IStudentDao dao;
10     
11     public void setDao(IStudentDao dao) {
12         this.dao = dao;
13     }
14 
15     @Override
16     public void addStudent(Student student) {
17         dao.insertStudent(student);
18     }
19 
20     @Override
21     public void removeStudent(int id) {
22         dao.deleteStudent(id);
23     }
24 
25     @Override
26     public void modifyStudent(Student student) {
27         dao.updateStudent(student);
28     }
29 
30     @Override
31     public String findStudentNameById(int id) {
32         return dao.selectStudentNameById(id);
33     }
34 
35     @Override
36     public List<String> findStudentNames() {
37         return dao.selectStudentNames();
38     }
39 
40     @Override
41     public Student findStudentById(int id) {
42         return dao.selectStudentById(id);
43     }
44 
45     @Override
46     public List<Student> findStudents() {
47         return dao.selectStudents();
48     }
49 
50 }

 

    (7)配置Spring配置文件:

 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" xsi:schemaLocation="
 5         http://www.springframework.org/schema/beans 
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context 
 8         http://www.springframework.org/schema/context/spring-context.xsd">
 9     
10     <!-- 注册数据源:Spring默认的数据源 -->
11     <!-- <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
12         <property name="driverClassName" value="com.mysql.jdbc.Driver" />
13         <property name="url" value="jdbc:mysql:///mytest" />
14         <property name="username" value="root" />
15         <property name="password" value="248xiaohai" />
16     </bean> -->
17     
18     <!-- 注册数据源:DBCP数据源 -->
19     <!--<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
20         <property name="driverClassName" value="com.mysql.jdbc.Driver" />
21         <property name="url" value="jdbc:mysql:///mytest" />
22         <property name="username" value="root" />
23         <property name="password" value="248xiaohai" />
24     </bean> -->
25     
26     <!-- 注册数据源:C3P0数据源 -->
27     <!-- <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
28         <property name="driverClass" value="com.mysql.jdbc.Driver" />
29         <property name="jdbcUrl" value="jdbc:mysql:///mytest" />
30         <property name="user" value="root" />
31         <property name="password" value="248xiaohai" />
32     </bean> -->
33     
34     <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
35         <property name="driverClass" value="${jdbc.driverClass}" />
36         <property name="jdbcUrl" value="${jdbc.url}" />
37         <property name="user" value="${jdbc.user}" />
38         <property name="password" value="${jdbc.password}" />
39     </bean>
40     <!-- 注册JDBC属性文件 -->
41     <!-- <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
42         <property name="location" value="classpath:jdbc.properties"/>
43      </bean> -->
44     
45     <!-- 注册JDBC属性文件 -->
46     <context:property-placeholder location="classpath:jdbc.properties"/>
47     
48     <!-- 注册JDBC模板对象,不用注册-->
49     <!-- <bean id="myJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
50         <property name="dataSource" ref="myDataSource"/>
51     </bean>
52     <bean id="studentDao" class="com.tongji.dao.StudentDaoImpl">
53         <property name="jdbcTemplate" ref="myJdbcTemplate"/>
54     </bean> -->
55     
56     <!-- 注册Dao -->
57     <bean id="studentDao" class="com.tongji.dao.StudentDaoImpl">
58         <property name="dataSource" ref="myDataSource"/>
59     </bean>
60     <!-- 注册Service -->
61     <bean id="studentService" class="com.tongji.service.StudentServiceImpl">
62         <property name="dao" ref="studentDao"></property>
63     </bean>    
64 </beans>

    Spring配置文件的解释:

    (1)数据源的配置
      使用 JDBC 模板,首先需要配置好数据源,数据源直接以 Bean 的形式配置在 Spring 配置文件中。根据数据源的不同,其配置方式不同。下面主要讲解三种常用数据源的配置方式:  
        (1)Spring 默认的数据源  
        (2)DBCP 数据源  
        (3)C3P0 数据源
    (2)从属性文件读取数据库连接信息
      为了便于维护,可以将数据库连接信息写入到属性文件中,使 Spring 配置文件从中读取数据。属性文件名称随意,但一般都是放在 src 下。

      Spring 配置文件从属性文件中读取数据时,需要在<property/>的 value 属性中使用${ },将在属性文件中定义的 key 括起来,以引用指定属性的值。

      该属性文件若要被 Spring 配置文件读取,其必须在配置文件中进行注册。注册方式有两种:  
        (1)<bean/>方式  
        (2)<context>方式  (见代码)
    (3)Dao和Service的配置:

      注意:Dao只要手动注入数据源对象。

 

    (8) 测试类:

 1 package com.tongji.test;
 2 
 3 import java.util.List;
 4 
 5 import org.junit.Before;
 6 import org.junit.Test;
 7 import org.springframework.context.ApplicationContext;
 8 import org.springframework.context.support.ClassPathXmlApplicationContext;
 9 
10 import com.tongji.beans.Student;
11 import com.tongji.service.IStudentService;
12 
13 public class MyTest {
14     
15     private IStudentService service;
16 
17     @Before
18     public void before() {
19         //创建容器
20         @SuppressWarnings("resource")
21         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
22         service = (IStudentService) ac.getBean("studentService");
23     }
24     
25     @Test
26     public void testAdd() {
27         service.addStudent(new Student("张三", 23));
28     }
29     
30     @Test
31     public void testRemove() {
32         service.removeStudent(1);
33     }
34     
35     @Test
36     public void testModify() {
37         Student student = new Student("李四", 24);
38         student.setId(2);
39         service.modifyStudent(student);
40     }
41     
42     @Test
43     public void testFindNameById() {
44         String name = service.findStudentNameById(2);
45         System.out.println(name);
46     }
47     
48     @Test
49     public void testFindStudentNames() {
50         List<String> name = service.findStudentNames();
51         System.out.println(name);
52     }
53     
54     @Test
55     public void testFindStudentById() {
56         Student student = service.findStudentById(2);
57         System.out.println(student);
58     }
59     
60     @Test
61     public void testFindStudents() {
62         List<Student> students = service.findStudents();
63         for (Student student : students) {
64             System.out.println(student);
65         }
66     }
67 }

 

  补充:JDBC 模板对象是多例的
    JdbcTemplate 对象是多例的,即系统会为每一个使用模板对象的线程(方法)创建一个JdbcTemplate 实例,并且在该线程(方法)结束时,自动释放 JdbcTemplate 实例。所以在每次使用 JdbcTemplate 对象时,都需要通过 getJdbcTemplate()方法获取。

 

posted @ 2017-02-04 16:00  拉夫德尔  阅读(413)  评论(0编辑  收藏  举报