Spring持久化
1. Spring的DAO理念
Spring提供了一套抽象的DAO类,供开发者扩展,这有利于以统一的方式操作各种DAO技术,如JDO、JDBC等,这些抽象DAO类提供了设置数据源及相关辅助信息的方法,而其中的一些方法同具体DAO技术相关。目前,SpringDAO抽象提供了以下几种类。
- JdbcDaoSupport:JDBC DAO抽象类,开发者需要为它设置数据源(DataSource),通过子类,开发者能够获得JdbcTemplate来访问数据库。
- HibernateDaoSupport:Hibernate DAO抽象类。开发者需要为它配置Hibernate SessionFactory。通过其子类,开发者能够获得Hibernate的实现。
- JdoDaoSupport:Spring为JDO提供了DAO抽象类,开发者需要为它配置PersistenceManagerFactory,通过其子类开发者能够获得JdoTemplate。
在使用Spring的DAO框架进行数据库存取时,无须接触使用特定的数据库技术,通过一个数据存取接口来操作即可。
例1.1 在Spring中利用DAO模式向tb_user表中添加数据。
(1)定义一个实体类对象User,然后在类中定义对应的数据库表字段的属性。关键代码如下:
package com.cn.aop; public class User {
private Integer id;
private String name;
private Integer age;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
(2)创建接口UserDAOImpl,并定义用来执行数据添加的insertUser()方法。其中insertUser()方法中使用的参数是User实体对象。代码如下:
package com.cn.aop; public interface UserDAOImpl {
public void insertUser(User user); //添加用户信息的方法
}
(3)编写实现这个DAO接口的UserDAO类,并在该类中实现接口中定义的方法。首先定义一个用于操作数据库的数据源对象DataSource,通过它创建一个数据库连接对象建立与数据库的连接,这个数据源对象在Spring中提供了javax.sql.DataSource接口的实现,只需要在Spring的配置文件中进行相关的配置即可,稍后会有关于Spring的配置文件。这个类中实现了接口的抽象方法insertUser()方法,通过这个方法访问数据库,关键代码如下:
package com.cn.aop; import java.sql.Connection;
import java.sql.SQLException; import javax.sql.DataSource; import java.sql.PreparedStatement; public class UserDAO implements UserDAOImpl {
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
//向数据表tb_user中添加数据
@Override
public void insertUser(User user) {
String name = user.getName();
Integer age = user.getAge();
String sex = user.getSex();
Connection conn = null;
PreparedStatement ps = null;
try {
//获取数据库连接
conn = dataSource.getConnection();
//添加数据的SQL语句
String sql = "insert into tb_user(name,age,sex) values(?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, name);
ps.setInt(2, age);
ps.setString(3, sex);
//执行SQL语句
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
ps.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } } }
(4)编写Spring的配置文件applicationContext.xml,在这个配置文件中首先定义一个JavaBean名称为DataSource的数据源,它是Spring中的DriverManagerDataSource类的实例。然后再配置前面编写完userDAO类,并且注入它的DataSource属性值。具体配置代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd"> <!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>1234</value>
</property>
</bean>
<!-- 为UserDAO注入数据源 -->
<bean id="userDAO" class="com.cn.aop.UserDAO">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
</beans>
(5)创建类Manager,在其main()方法中的关键代码如下:
package com.cn.aop; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; public class Manger {
public static void main(String[] args){
//装载配置文件
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
//实例化User对象
User user = new User();
user.setName("张三");
user.setAge(new Integer(30));
user.setSex("男");
//获取UserDAO
UserDAO userDAO = (UserDAO) factory.getBean("userDAO");
//执行添加方法
userDAO.insertUser(user);
System.out.println("数据添加成功!");
}
}
程序运行后,数据表tb_user添加的数据如下图所示:
2. 事务应用的管理
事务的管理通常分为两种方式,即编程式事务管理和声明式事务管理,在Spring中这两种事务管理方式都非常优秀。
- 编程式事务管理
在Spring中主要有两种编程式事务的实现方法,分别使用PlatformTransactionManager接口的事务管理器或TransactionTemplate实现。虽然两者各有优缺点,但是推荐使用TransactionTemplate实现方式,因为它符合Spring的模板模式。
说明:TransactionTemplate模板和Spring的其他模板一样,它封装了资源的打开和关闭等常用的重复代码,在编写程序的时候只需要完成需要的业务代码即可。
例2.1 利用TransactionTemplate实现Spring编程式事务管理。
(1)首先要在Spring的配置文件中声明事务管理器和TransactionTemplate并为TransactionExample配置相关信息,关键代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd"> <!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>1234</value>
</property>
</bean> <!-- 定义TransactionTemplate模板 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager">
<ref bean="transactionManager"/>
</property>
<property name="propagationBehaviorName">
<value>PROPAGATION_REQUIRED</value>
</property>
</bean>
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"></ref>
</property>
</bean>
<!-- 为TransactionExample注入数据源 -->
<bean id="transactionExample" class="com.cn.aop.TransactionExample">
<property name="dataSource">
<ref local="dataSource"/>
</property>
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="transactionTemplate">
<ref local="transactionTemplate"/>
</property>
</bean>
</beans>
(2)创建类TransactionExample,定义数据添加的方法,在方法中执行两次数据库添加的操作,并用事务对操作进行保护。关键代码如下:
package com.cn.aop; import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement; import javax.sql.DataSource; import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; public class TransactionExample {
DataSource dataSource; //注入数据源
PlatformTransactionManager transactionManager; //注入事务管理器
TransactionTemplate transactionTemplate; //注入TransactionTemplate模板
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public TransactionTemplate getTransactionTemplate() {
return transactionTemplate;
}
public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
this.transactionTemplate = transactionTemplate;
} public void transactionOperation() {
transactionTemplate.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
Connection conn = DataSourceUtils.getConnection(dataSource); //获得数据库连接
try {
Statement stmt = conn.createStatement();
//执行两次添加方法
stmt.execute("insert into tb_user(name,age,sex) values('小强','26','男')");
stmt.execute("insert into tb_user(name,age,sex) values('小红','22','女')");
System.out.println("操作执行成功!");
} catch (SQLException e) {
transactionManager.rollback(status);
System.out.println("操作执行失败,事务回滚!");
System.out.println("原因:"+e.getMessage());
}
return null;
} });
}
}
(3)创建类Manger,在其main()方法中的代码如下:
package com.cn.aop; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; public class Manger2 { public static void main(String[] args) {
//装载配置文件
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
//获取TransactionExample
TransactionExample transactionExample = (TransactionExample) factory.getBean("transactionExample");
//执行添加方法
transactionExample.transactionOperation();
} }
(4)为了测试事务是否配置正确,在transactionOperation()方法中执行两次添加操作的语句之间添加两句代码,制造人为异常。也就是说,当第一条操作语句执行成功后,第二天语句因为程序的异常无法执行成功,这种情况下如果事务成功回滚说明事务配置成功,添加的代码如下:
int a=0;
a=8/a;
程序执行后控制台会输出相关信息。
- 声明式事务管理
Spring的声明式事务不涉及组建依赖关系,它通过AOP实现事务管理,Spring本身就是一个容器,相对EJB容器而言,Spring显得更为轻便小巧。在使用Spring的声明式事务时无须编写任何代码,便可通过实现基于容器的事务管理。Spring提供了一些可供选择的辅助类,这些辅助类简化了传统的数据库操作流程,在一定程度上节省了工作量,提高了编程效率,所以推荐使用声明式事务。
在Spring中常用TransactionProxyFactoryBean完成声明式事务管理。
例2.2 利用TransactionProxyFactoryBean实现Spring声明式事务管理。
(1)首先在配置文件中定义数据源DataSource和事务管理器,这个事务管理器被注入到TransactionProxyFactoryBean中,设置代理对象和事务属性。这里的目标对象是以内部类的方式定义的。配置文件中的关键代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>1234</value>
</property>
</bean>
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref bean="dataSource"></ref>
</property>
</bean>
<!-- 定义TransactionProxy -->
<bean id="transactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="transactionManager"/>
</property>
<property name="target">
<bean id="addDAO" class="com.cn.dao.AddDAO">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
</property>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
</beans>
(2)其次编写操作数据库的AddDAO类,该类中的addUser()方法是关键,在该方法中执行了两次数据的插入操作,其在配置TransactionProxyFactoryBean时被定义为事务性方法,并指定了事务属性,所以方法中的所有数据库操作都被当作一个事务处理。类中的代码如下:
package com.cn.dao; import org.springframework.jdbc.core.support.JdbcDaoSupport; import com.cn.aop.User; public class AddDAO extends JdbcDaoSupport {
//添加用户方法
public void addUser(User user) {
//执行添加的SQL语句
String sql = "insert into tb_user(name,age,sex) values('"+
user.getName()+"','"+user.getAge()+"','"+user.getSex()+"')";
//执行两次添加方法
getJdbcTemplate().execute(sql);
getJdbcTemplate().execute(sql);
}
}
(3)创建类Manger,在其main()方法中的代码如下:
package com.cn.dao; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import com.cn.aop.AddDAO;
import com.cn.aop.User; public class Manger { public static void main(String[] args) {
//装载配置文件
Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
//获得AddDAO
AddDAO addDAO = (AddDAO) factory.getBean("transactionProxy");
//实例化User对象
User user = new User();
user.setName("张三");
user.setAge(new Integer(30));
user.setSex("男");
//执行数据库添加方法
addDAO.addUser(user);
} }
Spring持久化的更多相关文章
- Spring持久化之MyBatis
MyBatis是一个优秀的轻量级持久化框架,本文主要介绍MyBatis与Spring集成的配置与用法. 1. Spring MyBatis配置 1.1 添加Maven依赖 在pom.xml文件里添加m ...
- Spring企业级程序设计 • 【第4章 Spring持久化层和事务管理】
全部章节 >>>> 本章目录 4.1 配置数据源资源 4.1.1 JdbcTemplate介绍 4.1.2通过ComboPooledDataSource创建数据源 4.1. ...
- spring事务管理器设计思想(一)
在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...
- Spring 管理数据源
Spring 管理数据源 不管通过何种持久化技术,都必须通过数据连接访问数据库,在Spring中,数据连接是通过数据源获得的.在以往的应用中,数据源一般是Web应用服务器提供的.在Spring中,你不 ...
- 使用Maven管理Spring
原文链接: Spring with Maven原文日期: 2013年04月17日翻译日期: 2014年06月29日翻译人员: 铁锚 1. 概述本教程向您展示怎样通过 Maven 管理 Spring 的 ...
- 使用Maven管理Spring[转]
原文链接: Spring with Maven 原文日期: 2013年04月17日 翻译日期: 2014年06月29日 翻译人员: 铁锚 翻译原文连接:http://blog.csdn.net/ren ...
- 2.Spring——maven依赖
1.spring-core 2.spring-context 3.spring-orm 4.spring-web spring-webmvc others pmo demo1 pmo demo2 1. ...
- Spring的使用
Spring的组成 1. Core模块 该模块是Spring的核心容器,它实现了Ioc模式和Spring框架的基础功能. 2. Context模块 该模块继承BeanFactory类,并添加了事件处理 ...
- Spring企业级程序设计 • 【目录】
章节 内容 实践练习 Spring企业级程序设计目录(作业笔记) 第1章 Spring企业级程序设计 • [第1章 Spring之旅] 第2章 Spring企业级程序设计 • [第2章 Spring ...
随机推荐
- GUC-4 CopyOnWriteArrayList/CopyOnWriteArraySet
/* * CopyOnWriteArrayList/CopyOnWriteArraySet : “写入并复制” * 注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常的大.并发迭代操作多 ...
- python存取数据进阶技巧-pickle,array模块
我们在存/取数据时,没有必要存成文本形式,多试试二进制形式,文本只是骗骗眼睛的,要更快和更高效 1.数组形式 如果我们需要一个之包含数字的列表,那就试试array.array,注意,不是numpy模块 ...
- Technology share: VR is coming,are you ready?
►Date 2016-10-18 ►Address 上海市浦东新区严家桥1号宏慧音悦湾3号楼5楼 VR SPACE ►Events 品牌如何抢先一步,借玩VR吸引眼球,如何让客户作为VR买单? 如何结 ...
- SaltStack配置管理--状态间的关系(六)
一.include的引用 需求场景:用于含有多个SLS的状态,使用include可以进行多个状态的组合,将安装apache,php,mysql集合在一个sls中 [root@7mini-node1 p ...
- 【Spark亚太研究院系列丛书】Spark实战高手之路-第3章Spark架构设计与编程模型第3节:Spark架构设计(2)
三,深入RDD RDD本身是一个抽象类,具有很多具体的实现子类: RDD都会基于Partition进行计算: 默认的Partitioner如下所示: 其中HashPartitioner的文档说明如下: ...
- SQL Server 执行计划分析
当一个查询到达数据库引擎时,SQL Server执行两个主要的步骤来产生期望的查询结果: 第一步:查询编译,生成查询计划. 第二步:执行这个查询计划. 1. 用于演示分析执行计划的查询语句 /* 查询 ...
- thinkphp5.0配置作用域
作用域 配置参数支持作用域的概念,默认情况下,所有参数都在同一个系统默认作用域下面.如果你的配置参数需要用于不同的项目或者相互隔离,那么就可以使用作用域功能,作用域的作用好比是配置参数的命名空间一样. ...
- .htaccess文件
前言 看了几篇文章,发现自己对于如何维护普通的服务器安全完全不会,先从简单的.htaccess来研究吧 .htaccess文件的作用,就是更改httpd.ini文件中的配置,但作用范围仅限当前文件夹 ...
- 洛谷P2231 [HNOI2002]跳蚤 [数论,容斥原理]
题目传送门 跳蚤 题目描述 Z城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持人会给该跳蚤发一张卡片.卡片上写有N+ ...
- RabbitMQ (一)
学习RabbitMQ 可以先先了解一下AMQP 简单介绍: AMQP从一开始就设计成为开放标准,以解决众多的消息队列需求和拓扑结构问题,凭借开发,任何人都可以执行这一标准.针对标准编码的任何人都可以和 ...