DAO(Data Access Object)是用于访问数据的对象,虽然在大多数情况下将数据保存在数据库中,但这并不是唯一的选择,也可以将数据存储到文件中或LDAP中。DAO不但屏蔽了数据的最终介质的不同,也屏蔽了具体的实现技术的不同。
早期,JDBC是访问数据库的主流选择。近几年,随这个数据持久化技术获得了长足的发展,Hibernate、Mybatis等技术成为持久层框架的更好选择。
Spring统一数据访问模板
到一个餐馆用餐,大抵会经历这样一个流程:进入餐馆→服务人员问候并领到合适位置→拿起菜单点菜→用餐→买单→离开餐馆。之所以我们喜欢时不时到餐馆用餐,就是因为我们只要点菜→用餐→买单就可以了,其他工作我们不关心,餐馆完成即可。
在直接使用具体的持久化技术时,大多需要处理整个流程,程序员并没有享受到“餐馆用餐”般的好体验。Spring为支持持久化技术分别提供了模板访问的方式,降低了使用各种持久化技术的难度,因此可大幅度地提高开发效率。
使用模板和回调机制
我们来看一下传统的JDBC连接方式:
Class.forName("JDBC驱动类的名称");
Connection con = null;
PreparedStatement stmt = null;
try{
//1.获取资源
con= DriverManager.getConnection(数据库连接字符串,数据库用户名,密码);
//2.启动事务
con.setAutoCommit(false);
//3.具体业务逻辑
stmt=con.prepareStatement("插入数据");
//4.提交事务
con.commit();
} catch(Exception e){
try{
//5.回滚事务
con.rollback();
} catch...
...
//6.关闭资源
stmt.close();
con.close();
如上述代码所示,JDBC数据访问数据操作按一下流程进行:(1)准备资源(2)启动事务(3)在事务中执行具体的数据访问操作(4)提交/回滚事务(5)关闭资源,处理异常。
按照传统的方式,在编写任何带事务的数据访问程序时,都需要重复编写上面的代码,而其中只有具体业务逻辑和业务相关,其他代码都是重复的。
Spring将这个相同的数据访问流程固化到模板中,并将数据访问中固定和变化的部分分开,同时保证模板类是线程安全的,以便多个数据访问线程共享同一个模板实例。固定的部分在模板类中已经准备好,而变化的部分通过回调接口开放处理,用于定义具体数据访问和结果返回的操作,如下图:
这样,只要编写好回调接口,并调用模板类进行数据访问,就能得到预期的结果:数据访问成功执行,前置和后置的样板化工作也按顺序正确执行,在提高开发效率的同时也保证了资源使用的正确性,彻底消除了因忘记资源释放而引起的资源泄露问题。
Spring为不同持久化技术提供模板
Spring为各种支持的持久化技术都提供了建行操作的模板和回调,在回调中编写具体的数据操作逻辑,使用模板执行数据操作,这是Spring中典型的数据操作模式。我们会介绍其中几个。
数据源
不管使用何种持久化技术,都必须拥有数据连接。在Spring中,数据连接是通过数据源获得的。在以往的应用中,数据源一般是由Web应用服务器提供的。在Spring中,不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,此外,还可以通过代码的方式创建一个数据源。
配置一个数据源
Spring在第三方依赖包中包含了两个数据源的实现类包:DBCP
和C3P0
。这个应该里都用过,我们可以在Spring文件中利用二者中的任何一个配置数据源。使用前请加入依赖包。
1.DBCP数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/test"
p:username="root"
p:password="123456"
/>
</beans>
2.C3P0数据源
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
p:driverClass="com.mysql.jdbc.Driver"
p:jdbcUrl="jdbc:mysql://localhost:3306/test"
p:user="root"
p:password="123456"
/>
当然,它们的属性不仅仅于此,还有什么最大连接数,空闲时间之类等,此处不做介绍,具体环境具体应用。
3.JNDI数据源(了解)
4.Spring的数据源实现类(了解)
使用属性文件
数据源的配置信息有可能经常需要改动,同时可能被其他工程复用。此外,用户名、密码等信息比较敏感,可能需要加密措施。所以一般将数据源的配置信息独立到一个属性文件中,通过<context:property-placeholder>
引入属性文件,以${xxx}
的方式引用属性即可,代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
//引入WEB-INF目录下的文件
<context:property-placeholder location="WEB-INF/db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClass}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
/>
</beans>
在WEB-INF
目录下创建的db.properties
文件:
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=123
此处,属性文件的内容是以明文方式存放的,也可进行加密,此处不介绍。
Spring的JDBC访问数据库(了解即可)
前面说过传统的JDBC方式的缺点,Spring通过目标和回调机制大大降低了使用JDBC的复杂度,借由JdbcTemplate
的帮助,仅需要编写那些“必不可少”的代码就可以进行数据库操作,而将资源获取、Statement创建、资源释放及异常处理等繁杂且乏味的工作交给Spring JDBC。
什么是JdbcTemplate?
JdbcTemplate
类是Spring框架数据抽象层的基础,它是Spring JDBC的核心类,继承结构如下:
从
JdbcTemplate
继承关系图可以看出,JdbcTemplate
的直接父类是JdbcAccessor
,该类为子类提供了一些访问数据库时的公用属性。
-
DataSource
:其主要功能是获取数据库的连接,还可以引入对数据库连接的缓存池和分布式事务的支持,它可以作为访问数据库资源的标准接口。 -
SQLExceptionTranslator
:该接口负责对SQLException
进行转译工作。通过必要的设置获取SQLExceptionTranslator
的方法,可以使JdbcTemplate
在需要处理SQLException
时,委托给SQLExceptionTranslator
的实现类来完成相关的转译工作。
而JdbcOperations
接口定义了在JdbcTemplate
类中可以使用的操作集合,包括添加、修改、查询和删除等操作。
使用JdbcTemplate
几乎可以使用JdbcTemplate
完成任何数据访问操作,并充分享受它带来的简洁。它的使用方式有两种:
1.代码方式实现(了解即可)
//创建数据源并设置相关信息
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("");
ds.setUrl("");
ds.setUsername("");
ds.setPassword("");
JdbcTemplate jtp = new JdbcTemplate();
//设置数据源
jtp.setDataSource(ds);
String sql = "create table user(user_id int ,username varchar(50))";
jtp.insert(sql);
2.配置文件使用(常用)
当然,我们一般都是在配置文件中配置,直接在DAO中注入即可:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描相应包注册以注解方式声明的Bean-->
<context:component-scan base-package="cn"/>
<!--1.定义数据源-->
<context:property-placeholder location="WEB-INF/db.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClass}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
/>
<!--2.声明JdbcTemplate,并引用相应数据源-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="dataSource"/>
</beans>
然后在DAO中注入即可:
@Repository
public class UserDao{
private JdbcTemplate jdbcTemplate;
@Autowired
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate = jdbcTemplate;
}
public void saveUser(){
String sql ="sql语句";
jdbcTemplate.execute(sql);
}
}
jdbcTemplate的数据库操作方法
数据库的增、删、查、改及存储过程调用是最常见的数据库操作,jdbcTemplate
提供了众多方法完成这些数据操作。
-
execute:
用于执行sql语句。 -
update:
:用于执行插入、更新和删除操作。 -
query:
用于执行数据查询操作。
不详细介绍了,因为我们一般都用Mybatis框架来代替Spring自带的JDBC。
参考资料
《精通Spring 4.x 企业应用开发》