Spring之DAO

前面整理了IOC、AOP的实现方式,今天称热打铁复习一下SpringDAO。

JdbcTemplate

SpringDAO的核心类是JdbcTemplate,全限定名为org.springframework.jdbc.core.JdbcTemplate。可能你会看到JdbcDaoSupport这个类也是里边的核心,但是其实JdbcDaoSupport这个类里边有一个类型为JdbcTemplate的属性,最后执行sql语句的时候还是用的JdbcDaoSupport的getJdbcTemplate()方法得到JdbcTemplate之后再通过JdbcTemplate类的方法来执行。

JdbcTemplate对JDBC的差别在哪?
JDBC需要每次进行数据库连接, 然后处理SQL语句,传值,关闭数据库。
甚至有时还可能会出现数据库忘记关闭导致连接被占用。
在以后的工作中,客户的需求肯定不是一成不变的,这就导致经常会改动数据库内容.
通过JDBCtemplate我们只需更改需要更改的那一部分内容就可以了,不需要进行全局修改。Spring将替我们完成所有的JDBC底层细节处理工作。

JdbcTemplate主要提供以下五类方法:

  • execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句; * batchUpdate方法用于执行批处理相关语句;
  • query方法及queryForXXX方法:用于执行查询相关语句;
  • call方法:用于执行存储过程、函数相关语句。

SpringDAO的实现

建立表格:

1
2
3
4
5
6
7
8
CREATE TABLE `students` (
`student_id` int(11) NOT NULL AUTO_INCREMENT,
`student_name` varchar(20) NOT NULL,
`student_sex` char(1) DEFAULT NULL,
`student_birthday` date DEFAULT NULL,
`group_id` varchar(20) DEFAULT NULL,
PRIMARY KEY (`student_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

POJO:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.aowin.testspring.dao.pojo;

import java.io.Serializable;
import java.sql.Date;

public class Students implements Serializable {

private Integer studentid;
private String studentname;
private String studentsex;
private Date studentbirthday;
private String groupid;

public Students() {

}

public Integer getStudentid() {
return studentid;
}

public void setStudentid(Integer studentid) {
this.studentid = studentid;
}

public String getStudentname() {
return studentname;
}

public void setStudentname(String studentname) {
this.studentname = studentname;
}

public String getStudentsex() {
return studentsex;
}

public void setStudentsex(String studentsex) {
this.studentsex = studentsex;
}

public Date getStudentbirthday() {
return studentbirthday;
}

public void setStudentbirthday(Date studentbirthday) {
this.studentbirthday = studentbirthday;
}

public String getGroupid() {
return groupid;
}

public void setGroupid(String groupid) {
this.groupid = groupid;
}

@Override
public String toString() {
return "Students [studentid=" + studentid + ", studentname=" + studentname + ", studentsex=" + studentsex
+ ", studentbirthday=" + studentbirthday + ", groupid=" + groupid + "]";
}

}

DAO接口:

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
package com.aowin.testspring.dao;

import java.util.List;

import com.aowin.testspring.dao.pojo.Students;

public interface IStudentDAO {

String INSERT_STUDENT_SQL = "insert into students (student_name,student_sex,student_birthday,group_id)" +
"values(?,?,?,?)";
String SELECT_STUDENT_ALL_SQL ="select student_id,student_name,student_sex,student_birthday,group_id from students";
String SELECT_STUDENT_COUNT_SQL ="select count(student_id) total from students";
/**
* 添加学生信息
* @param student学生信息
* @return 是否添加成功
*/
public boolean insertStudent(Students student);

/**
* 获取所有学生信息
* @return 所有学生信息
*/
public List<Students> selectStudents();

/**
* 获取学生总人数
* @return
*/
public int selectTotalRocords();
}

SpringDAO的实现有两种方式。

继承JdbcDaoSupport

我们写一个实现类实现IStudentDAO接口,并且继承JdbcDaoSupport类:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.aowin.testspring.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.aowin.testspring.dao.pojo.Students;

public class StudentDAOImpl0 extends JdbcDaoSupport implements IStudentDAO {

public StudentDAOImpl0() {
// TODO Auto-generated constructor stub
}
//实现数据添加方法
public boolean insertStudent(Students student) {
boolean result = false;
//通过update方法执行接口中的SQL语句,并且将SQL语句参数传递进去
int i = super.getJdbcTemplate().update(INSERT_STUDENT_SQL,student.getStudentname(),
student.getStudentsex(),student.getStudentbirthday(),student.getGroupid());
//如果成功添加
if(i > 0)
result = true;
return false;
}
//实现获取所有学生信息方法
public List<Students> selectStudents() {
//通过query方法执行接口中的SQL语句,并封装返回的数据
return super.getJdbcTemplate().query(SELECT_STUDENT_ALL_SQL, new RowMapper<Students>() {
//封装数据返回的数据
public Students mapRow(ResultSet rs, int rowNum) throws SQLException {
Students student = new Students();
student.setGroupid(rs.getString("group_id"));
student.setStudentbirthday(rs.getDate("student_birthday"));
student.setStudentname(rs.getString("student_name"));
student.setStudentsex(rs.getString("student_sex"));
return student;
}
});
}
//实现获取全部学生数方法
public int selectTotalRocords() {
//通过queryForObject方法执行接口中的SQL语句,并声明返回类型。
return super.getJdbcTemplate().queryForObject(SELECT_STUDENT_COUNT_SQL, Integer.class);
}
}

程序中所做的事无非就是执行JdbcTemplate的方法在执行SQL语句,其操作和JDBC对比起来,程序并不需要考虑与数据库的连接获取、关闭数据库连接等事情,只需执行我们的SQL语句即可。
配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 配置数据源 -->	
<bean id="dmds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 数据库连接所必要的数据 -->
<!-- 数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<!-- 数据库url -->
<property name="url" >
<value>jdbc:mysql://localhost:3306/testmybatis?useUnicode=true&amp;characterEncoding=utf8</value>
</property>
<!-- 用户名 -->
<property name="username" value="root"></property>
<!-- 密码 -->
<property name="password" value="123"></property>
</bean>

<!-- 配置测试类,将数据源注入-->
<bean id="studentDao" class="com.aowin.testspring.dao.StudentDAOImpl0">
<property name="dataSource" ref="dmds"></property>
</bean>

在配置文件中我们可以看到,因为要连接数据库,我们对数据源的配置是必不可少的。我们需要配置DriverManagerDataSource类,并且给它注入连接数据库必须的属性(DriverManager、url、username、password)。看到配置文件可能有人会疑惑,StudentDAOImpl0这个类并没有dataSource属性,为何可以注入数据源呢?其实我们继承的JdbcDaoSupport类中有 setDataSource(DataSource dataSource) 方法,所以我们可以直接执行注入操作。在SpringDAO低耦合操作中,我们可以不再继承JdbcDaoSupport,而是直接设置JdbcTemplate属性并增加相应的set/get方法。
测试类中(这里我们只测试InsertStudent()方法):

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void test(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("springJDBC.xml");
IStudentDAO studentDao = context.getBean("studentDao",IStudentDAO.class);
Students students = new Students();
students.setStudentname("德莱文");
students.setStudentsex("1");
students.setStudentbirthday(java.sql.Date.valueOf("2014-10-1"));
students.setGroupid("S3");
studentDao.insertStudent(students);
}

运行结果:

可以看到数据成功的插入。

低耦合方式

低耦合的实现方式中,我们不再继承JdbcDaoSupport类,而是给我们的实现类设置JdbcTemplate接口。
也就是在前面的这种实现方式中添加:

1
2
3
4
5
6
7
8
9
10
@Autowired 
private JdbcTemplate template;

public StudentDAOImpl() {
// TODO Auto-generated constructor stub
}

public JdbcTemplate getTemplate() {
return template;
}

并且不再继承JdbcDaoSupport。再修改实现类类名为:StudentDAOImpl
在配置文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- 开启注解 -->
<context:annotation-config />

<!-- 配置数据源 -->
<bean id="dmds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 数据库连接所必要的数据 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" >
<value>jdbc:mysql://localhost:3306/testmybatis?useUnicode=true&amp;characterEncoding=utf8</value>
</property>
<property name="username" value="root"></property>
<property name="password" value="123"></property>
</bean>
<!-- 配置JdbcTemplate -->
<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" ref="dmds"></constructor-arg>
</bean>

<!-- 声明实现类 -->
<bean id="studentDao" class="com.aowin.testspring.dao.StudentDAOImpl">
</bean>

JdbcTemplate中也需要注入dataSource属性,我们这里采用构造器注入。
在测试方法中(这里只测试insertStudent()方法):

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void test1(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("springJDBC2.xml");
IStudentDAO studentDao = context.getBean("studentDao",IStudentDAO.class);
Students students = new Students();
students.setStudentname("盖伦");
students.setStudentsex("1");
students.setStudentbirthday(java.sql.Date.valueOf("2012-10-1"));
students.setGroupid("s1");
studentDao.insertStudent(students);
}

执行结果:

可以看到方法执行成功。

说到SpringDAO不得不提到Spring中的事务处理,因为内容比较多我们再另起一篇。
Spring的事务处理

-------------本文结束感谢您的阅读-------------