为了对spring开启事务有进一步的了解,下面看这个简单的例子:
1 实体类User.java
- package org.lab24.entity;
- import java.io.Serializable;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.Table;
- @Entity
- @Table(name = "User")
- public class User
implements Serializable{ - public User(){
- }
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private Integer id;
- private String name;
- 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;
- }
- }
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "User")
public class User implements Serializable{
public User(){
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
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;
}
}
2 抽象dao类,这里设为抽象类主要是为了不让它直接实例化对象(这里这样设计好像有点多余,这个应该是一种设计模式吧):
- package org.lab24.dao;
- import java.util.List;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- public abstract
class BasicDao extends HibernateDaoSupport{
- //这里的返回值,可以直接返回getHibernateTemplate().save(entity)的值,这个会返回新插入记录的键值,也可以如下方式,返回一个持久化到数据库的对象
- public Object save(Object entity)
throws Exception{ - getHibernateTemplate().save(entity);
- return entity;
- }
- public List getAllObjects(Class object)throws Exception{
- return getHibernateTemplate().find("from " + object.getName());
- }
- //delete返回的是一个空值,因为记录都删除了,就不会有键值或对象的返回
- public void delete(Object entity)throws Exception{
- getHibernateTemplate().delete(entity);
- }
- }
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public abstract class BasicDao extends HibernateDaoSupport{
//这里的返回值,可以直接返回getHibernateTemplate().save(entity)的值,这个会返回新插入记录的键值,也可以如下方式,返回一个持久化到数据库的对象
public Object save(Object entity) throws Exception{
getHibernateTemplate().save(entity);
return entity;
}
public List getAllObjects(Class object)throws Exception{
return getHibernateTemplate().find("from " + object.getName());
}
//delete返回的是一个空值,因为记录都删除了,就不会有键值或对象的返回
public void delete(Object entity)throws Exception{
getHibernateTemplate().delete(entity);
}
}
3 dao实现类:
- package org.lab24.dao.impl;
- import java.util.List;
- import org.lab24.dao.BasicDao;
- import org.springframework.stereotype.Repository;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Propagation;
- import org.springframework.transaction.annotation.Transactional;
- /*
- * @Service用于标注业务层组件,
- * @Controller用于标注控制层组件(如struts中的action),
- * @Repository用于标注数据访问组件,即DAO组件,
- * 而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
- */
- @Repository("basicDaoService")
- /*
- * readOnly表示事务是否只读的,不能进行插入更新操作
- * propagation = Propagation.REQUIRED表示执行这个类实例方法需开启事务
- * rollbackFor = Throwable.class表示遇到Throwable类及子类(即发生了异常)时事务进行回滚操作
- */
- @Transactional(readOnly=false , propagation = Propagation.REQUIRED , rollbackFor = Throwable.class)
- public class BasicDaoImpl
extends BasicDao{ - @Override
- public Object save(Object entity)
throws Exception { - return super.save(entity);
- }
- @Override
- public void delete(Object entity)
throws Exception { - super.delete(entity);
- }
- @Override
- public List getAllObjects(Class object)
throws Exception { - List objectList = super.getAllObjects(object);
- return objectList;
- }
- }
import java.util.List;
import org.lab24.dao.BasicDao;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/*
* @Service用于标注业务层组件,
* @Controller用于标注控制层组件(如struts中的action),
* @Repository用于标注数据访问组件,即DAO组件,
* 而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
*/
@Repository("basicDaoService")
/*
* readOnly表示事务是否只读的,不能进行插入更新操作
* propagation = Propagation.REQUIRED表示执行这个类实例方法需开启事务
* rollbackFor = Throwable.class表示遇到Throwable类及子类(即发生了异常)时事务进行回滚操作
*/
@Transactional(readOnly=false , propagation = Propagation.REQUIRED , rollbackFor = Throwable.class)
public class BasicDaoImpl extends BasicDao{
@Override
public Object save(Object entity) throws Exception {
return super.save(entity);
}
@Override
public void delete(Object entity) throws Exception {
super.delete(entity);
}
@Override
public List getAllObjects(Class object) throws Exception {
List objectList = super.getAllObjects(object);
return objectList;
}
}
4 业务层接口类:
- package org.lab24.service;
- import java.util.List;
- import org.lab24.entity.User;
- public interface UserService {
- public void save(User user)throws Exception;
- public List getAllUsers()throws Exception;
- public void deleteUser(User user)throws Exception;
- }
import java.util.List;
import org.lab24.entity.User;
public interface UserService {
public void save(User user)throws Exception;
public List getAllUsers()throws Exception;
public void deleteUser(User user)throws Exception;
}
5 业务层实现类:
- package org.lab24.serviceImpl;
- import java.util.List;
- import javax.annotation.Resource;
- import org.lab24.dao.impl.BasicDaoImpl;
- import org.lab24.entity.User;
- import org.lab24.service.UserService;
- import org.springframework.stereotype.Service;
- @Service("userService")//自己给这个交给spring管理的bean一个名字,若不给,就直接用类的名字第一个字母改为小写而形成bean的名字
- public class UserServiceImpl
implements UserService{ - @Resource
- BasicDaoImpl basicDaoService;//basicDaoService对应BasicDaoImpl成为数据访问组件的bean名字
- public List getAllUsers()
throws Exception{ - List userList = basicDaoService.getAllObjects(User.class);
- return userList;
- }
- public void save(User user)
throws Exception{ - basicDaoService.save(user);
- }
- public void deleteUser(User user)
throws Exception { - basicDaoService.delete(user);
- }
- }
import java.util.List;
import javax.annotation.Resource;
import org.lab24.dao.impl.BasicDaoImpl;
import org.lab24.entity.User;
import org.lab24.service.UserService;
import org.springframework.stereotype.Service;
@Service("userService")//自己给这个交给spring管理的bean一个名字,若不给,就直接用类的名字第一个字母改为小写而形成bean的名字
public class UserServiceImpl implements UserService{
@Resource
BasicDaoImpl basicDaoService;//basicDaoService对应BasicDaoImpl成为数据访问组件的bean名字
public List getAllUsers() throws Exception{
List userList = basicDaoService.getAllObjects(User.class);
return userList;
}
public void save(User user) throws Exception{
basicDaoService.save(user);
}
public void deleteUser(User user) throws Exception {
basicDaoService.delete(user);
}
}
6 测试类:
- package org.lab24.junit.test;
- import java.util.Iterator;
- import java.util.List;
- import javax.annotation.Resource;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.lab24.entity.User;
- import org.lab24.service.UserService;
- import org.springframework.test.context.ContextConfiguration;
- import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- @ContextConfiguration(locations =
"classpath:applicationContext.xml")
- @RunWith(SpringJUnit4ClassRunner.class)
- public class UserServiceImplTest{
- @Resource
- private UserService userService;//userService对应UserServiceImpl成为服务组件的bean名字
- @BeforeClass
- public static
void setUpBeforeClass() throws Exception {
- }
- @Test
- public void testGetAllUsers() {
- List<User> users = null;
- try {
- users = userService.getAllUsers();
- } catch (Exception e) {
- e.printStackTrace();
- }
- Iterator iterator = users.iterator();
- User temp;
- while(iterator.hasNext()){
- temp = (User) iterator.next();
- System.out.println("ID:" + temp.getId() +
" name:" + temp.getName()); - }
- }
- @Test
- public void testSave() {
- User user = new User();
- user.setName("333333333");
- try {
- userService.save(user);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
import java.util.Iterator;
import java.util.List;
import javax.annotation.Resource;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.lab24.entity.User;
import org.lab24.service.UserService;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ContextConfiguration(locations = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class UserServiceImplTest{
@Resource
private UserService userService;//userService对应UserServiceImpl成为服务组件的bean名字
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void testGetAllUsers() {
List<User> users = null;
try {
users = userService.getAllUsers();
} catch (Exception e) {
e.printStackTrace();
}
Iterator iterator = users.iterator();
User temp;
while(iterator.hasNext()){
temp = (User) iterator.next();
System.out.println("ID:" + temp.getId() + " name:" + temp.getName());
}
}
@Test
public void testSave() {
User user = new User();
user.setName("333333333");
try {
userService.save(user);
} catch (Exception e) {
e.printStackTrace();
}
}
}
7 spring配置文件:
- <?xml
version="1.0"
encoding="UTF-8"?>
- <beans
xmlns="http://www.springframework.org/schema/beans"
- xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
- http://www.springmodules.org/schema/ehcache
- http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
- http://www.directwebremoting.org/schema/spring-dwr
- http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"
- default-autowire="byName"
default-lazy-init="true">
- <context:component-scan
base-package="org.lab24.dao.impl"
/> - <context:component-scan
base-package="org.lab24.serviceImpl"
/> - <bean
id="lobHandler"
class="org.springframework.jdbc.support.lob.DefaultLobHandler"
- lazy-init="true"
/> - <!-- 缓存管理 -->
- <bean
id="cacheManager"
- class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
- <property
name="configLocation">
- <value>classpath:ehcache.xml</value>
- </property>
- </bean>
- <bean
id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
> - <property
name="lobHandler"
ref="lobHandler"
/> - <property
name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration"
/> - <property
name="configLocation">
- <value>classpath:hibernate.cfg.xml</value>
- </property>
- </bean>
- <bean
id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property
name="sessionFactory"
ref="sessionFactory"
/> - </bean>
- <tx:annotation-driven
transaction-manager="transactionManager"
- proxy-target-class="true"
/> - <!-- 在此进行自动代理配置 -->
- <bean
id="beanNameAutoProxyCreator"
- class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <property
name="proxyTargetClass"
value="true"
/> - <property
name="beanNames">
- <list>
- <value>*Impl</value>
- </list>
- </property>
- </bean>
- </beans>
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springmodules.org/schema/ehcache
http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd
http://www.directwebremoting.org/schema/spring-dwr
http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"
default-autowire="byName" default-lazy-init="true">
<context:component-scan base-package="org.lab24.dao.impl" />
<context:component-scan base-package="org.lab24.serviceImpl" />
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler"
lazy-init="true" />
<!-- 缓存管理 -->
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath:ehcache.xml</value>
</property>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name="lobHandler" ref="lobHandler" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"
proxy-target-class="true" />
<!-- 在此进行自动代理配置 -->
<bean id="beanNameAutoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="proxyTargetClass" value="true" />
<property name="beanNames">
<list>
<value>*Impl</value>
</list>
</property>
</bean>
</beans>
8 hibernate配置文件:
- <?xml
version="1.0"
encoding="utf-8"
?> - <!DOCTYPE hibernate-configuration
- PUBLIC "-//Hibernate/Hibernate Configuration DTD/EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property
name="hibernate.connection.driver_class"
>com.mysql.jdbc.Driver</property>
- <property
name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <property
name="hibernate.connection.username">root</property>
- <property
name="hibernate.connection.password"></property>
- <property
name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/wtb</property>
- <!-- Connection Parameters -->
- <property
name="hibernate.connection.provider_class">
- org.hibernate.connection.C3P0ConnectionProvider
- </property>
- <!-- Connection Pool -->
- <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
- <property
name="hibernate.c3p0.acquireIncrement">3</property>
- <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
- <property
name="hibernate.c3p0.acquireRetryDelay">1000</property>
- <!--连接关闭时默认将所有未提交的操作回滚。Default: false -->
- <property
name="hibernate.c3p0.autoCommitOnClose">false</property>
- <!--连接池中保留的最大连接数。Default: 15 -->
- <property
name="hibernate.c3p0.maxPoolSize">15</property>
- <property
name="hibernate.c3p0.max_size">20</property>
- <property
name="hibernate.c3p0.min_size">5</property>
- <property
name="hibernate.c3p0.timeout">5000</property>
- <property
name="hibernate.c3p0.acquire_increment">5</property>
- <property
name="hibernate.c3p0.idle_test_period">3000</property>
- <property
name="hibernate.c3p0.preferredTestQuery">
- select id from test where
id=1 - </property>
- <property
name="hibernate.c3p0.testConnectionOnCheckin">
- true
- </property>
- <!-- 启动时删数据库中的表,然后创建,退出时不删除数据表,如果没有下面的属性的话,那么要手动写sql语句来建表,才能进行数据库的操作-->
- <property
name="hbm2ddl.auto">update</property>
- <!--
- 为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取.
- -->
- <property
name="hibernate.max_fetch_depth">3</property>
- <property
name="hibernate.order_updates">true</property>
- <property
name="hibernate.jdbc.fetch_size">100</property>
- <property
name="hibernate.jdbc.batch_size">0</property>
- <property
name="hibernate.show_sql">false</property>
- <property
name="hibernate.format_sql">true</property>
- <property
name="hibernate.ejb.naming_strategy">
- DefaultComponentSafeNamingStrategy
- </property>
- <property
name="hibernate.query.substitutions">
- true=1,
false=0
- </property>
- <property
name="hibernate.query.factory_class">
- org.hibernate.hql.ast.ASTQueryTranslatorFactory
- </property>
- <!--
- 2.0 <property
- name="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</property>
- -->
- <property
name="hibernate.cglib.use_reflection_optimizer">
- false
- </property>
- <property
name="hiberante.defaultAutoCommit">false</property>
- <property
name="hibernate.cache.provider_class">
- org.hibernate.cache.EhCacheProvider
- </property>
- <property
name="cache.use_second_level_cache">true</property>
- <!-- Transaction Configuration -->
- <property
name="hibernate.transaction.factory_class">
- org.hibernate.transaction.JDBCTransactionFactory
- </property>
- <mapping
class="org.lab24.entity.User"
/> - </session-factory>
- </hibernate-configuration>
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class" >com.mysql.jdbc.Driver</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.username">root</property>