之前的博文中我们搭建了一个基本的开发环境,现在让我们给这个项目加上CRUD和基本的单元测试。
1、创建泛型DAO的相关类
在src\main\java\com\ceair\app\dao下创建GenericDao.java(APPFUSE2中的代码),代码内容如下:
- package com.ceair.app.dao;
- import java.io.Serializable;
- import java.util.List;
- import java.util.Map;
- /**
- * Generic DAO (Data Access Object) with common methods to CRUD POJOs.
- *
- * <p>Extend this interface if you want typesafe (no casting necessary) DAO's for your
- * domain objects.
- *
- * @author <a href="mailto:bwnoll@gmail.com">Bryan Noll</a>
- * @param <T> a type variable
- * @param <PK> the primary key for that type
- */
- public interface GenericDao <T, PK extends Serializable> {
- /**
- * Generic method used to get all objects of a particular type. This
- * is the same as lookup up all rows in a table.
- * @return List of populated objects
- */
- List<T> getAll();
- /**
- * Generic method to get an object based on class and identifier. An
- * ObjectRetrievalFailureException Runtime Exception is thrown if
- * nothing is found.
- *
- * @param id the identifier (primary key) of the object to get
- * @return a populated object
- * @see org.springframework.orm.ObjectRetrievalFailureException
- */
- T get(PK id);
- /**
- * Checks for existence of an object of type T using the id arg.
- * @param id the id of the entity
- * @return - true if it exists, false if it doesn't
- */
- boolean exists(PK id);
- /**
- * Generic method to save an object - handles both update and insert.
- * @param object the object to save
- * @return the persisted object
- */
- T save(T object);
- /**
- * Generic method to delete an object based on class and id
- * @param id the identifier (primary key) of the object to remove
- */
- void remove(PK id);
- /**
- * Gets all records without duplicates.
- * <p>Note that if you use this method, it is imperative that your model
- * classes correctly implement the hashcode/equals methods</p>
- * @return List of populated objects
- */
- List<T> getAllDistinct();
- /**
- * Find a list of records by using a named query
- * @param queryName query name of the named query
- * @param queryParams a map of the query names and the values
- * @return a list of the records found
- */
- List<T> findByNamedQuery(String queryName, Map<String, Object> queryParams);
- }
在src\main\java\com\ceair\app\dao\hibernate中创建GenericDaoHibernate.java实现类,代码如下:
- package com.ceair.app.dao.hibernate;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.orm.ObjectRetrievalFailureException;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import com.ceair.app.dao.GenericDao;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- import java.util.LinkedHashSet;
- import java.util.List;
- import java.util.Map;
- /**
- * This class serves as the Base class for all other DAOs - namely to hold
- * common CRUD methods that they might all use. You should only need to extend
- * this class when your require custom CRUD logic.
- *
- * <p>To register this class in your Spring context file, use the following XML.
- * <pre>
- * <bean id="fooDao" class="org.appfuse.dao.hibernate.GenericDaoHibernate">
- * <constructor-arg value="org.appfuse.model.Foo"/>
- * <property name="sessionFactory" ref="sessionFactory"/>
- * </bean>
- * </pre>
- *
- * @author <a href="mailto:bwnoll@gmail.com">Bryan Noll</a>
- * @param <T> a type variable
- * @param <PK> the primary key for that type
- */
- public class GenericDaoHibernate<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> {
- /**
- * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging
- */
- protected final Log log = LogFactory.getLog(getClass());
- private Class<T> persistentClass;
- /**
- * Constructor that takes in a class to see which type of entity to persist
- * @param persistentClass the class type you'd like to persist
- */
- public GenericDaoHibernate(final Class<T> persistentClass) {
- this.persistentClass = persistentClass;
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public List<T> getAll() {
- return super.getHibernateTemplate().loadAll(this.persistentClass);
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public List<T> getAllDistinct() {
- Collection result = new LinkedHashSet(getAll());
- return new ArrayList(result);
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public T get(PK id) {
- T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id);
- if (entity == null) {
- log.warn("Uh oh, '" + this.persistentClass + "' object with id '" + id + "' not found...");
- throw new ObjectRetrievalFailureException(this.persistentClass, id);
- }
- return entity;
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public boolean exists(PK id) {
- T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id);
- return entity != null;
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public T save(T object) {
- return (T) super.getHibernateTemplate().merge(object);
- }
- /**
- * {@inheritDoc}
- */
- public void remove(PK id) {
- super.getHibernateTemplate().delete(this.get(id));
- }
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- public List<T> findByNamedQuery(
- String queryName,
- Map<String, Object> queryParams) {
- String []params = new String[queryParams.size()];
- Object []values = new Object[queryParams.size()];
- int index = 0;
- Iterator<String> i = queryParams.keySet().iterator();
- while (i.hasNext()) {
- String key = i.next();
- params[index] = key;
- values[index++] = queryParams.get(key);
- }
- return getHibernateTemplate().findByNamedQueryAndNamedParam(
- queryName,
- params,
- values);
- }
- }
在src\test\java\com\ceair\app\dao下创建单元测试基类BaseDaoTestCase.java,代码如下:
- package com.ceair.app.dao;
- import org.apache.commons.beanutils.BeanUtils;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.hibernate.SessionFactory;
- import org.springframework.orm.hibernate3.HibernateTemplate;
- import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
- import java.util.Enumeration;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.MissingResourceException;
- import java.util.ResourceBundle;
- /**
- * Base class for running DAO tests.
- * @author mraible
- */
- public abstract class BaseDaoTestCase extends AbstractTransactionalDataSourceSpringContextTests {
- /**
- * Log variable for all child classes. Uses LogFactory.getLog(getClass()) from Commons Logging
- */
- protected final Log log = LogFactory.getLog(getClass());
- /**
- * ResourceBundle loaded from src/test/resources/${package.name}/ClassName.properties (if exists)
- */
- protected ResourceBundle rb;
- /**
- * Sets AutowireMode to AUTOWIRE_BY_NAME and configures all context files needed to tests DAOs.
- * @return String array of Spring context files.
- */
- protected String[] getConfigLocations() {
- setAutowireMode(AUTOWIRE_BY_NAME);
- return new String[] {
- // "classpath:/applicationContext-resources.xml",
- "classpath:/applicationContext-dao.xml",
- "classpath*:/applicationContext.xml", // for modular projects
- "classpath:/applicationContext-hibernate.xml"
- // "classpath:**/applicationContext*.xml" // for web projects
- };
- }
- /**
- * Default constructor - populates "rb" variable if properties file exists for the class in
- * src/test/resources.
- */
- public BaseDaoTestCase() {
- // Since a ResourceBundle is not required for each class, just
- // do a simple check to see if one exists
- String className = this.getClass().getName();
- try {
- rb = ResourceBundle.getBundle(className);
- } catch (MissingResourceException mre) {
- //log.warn("No resource bundle found for: " + className);
- }
- // super.setDefaultRollback(false); //不回滚数据
- }
- /**
- * Utility method to populate a javabean-style object with values
- * from a Properties file
- * @param obj the model object to populate
- * @return Object populated object
- * @throws Exception if BeanUtils fails to copy properly
- */
- protected Object populate(Object obj) throws Exception {
- // loop through all the beans methods and set its properties from its .properties file
- Map<String, String> map = new HashMap<String, String>();
- for (Enumeration<String> keys = rb.getKeys(); keys.hasMoreElements();) {
- String key = keys.nextElement();
- map.put(key, rb.getString(key));
- }
- BeanUtils.copyProperties(map, obj);
- return obj;
- }
- /**
- * Create a HibernateTemplate from the SessionFactory and call flush() and clear() on it.
- * Designed to be used after "save" methods in tests: http://issues.appfuse.org/browse/APF-178.
- */
- protected void flush() {
- HibernateTemplate hibernateTemplate =
- new HibernateTemplate((SessionFactory) applicationContext.getBean("sessionFactory"));
- hibernateTemplate.flush();
- hibernateTemplate.clear();
- }
- }
这个类的注意点如下:
1、38-40行(
classpath:/applicationContext-dao.xml等)是指向你的配置文件,等下我会列出这些配置文件的详细信息。
2、去掉59行那句代码(
super.setDefaultRollback(false); )注释的话,如果有数据库操作,那么不回滚测试数据。
在src\main\resources下分别创建applicationContext.xml,applicationContext-dao.xml,applicationContext-hibernate.xml 我们把applicationContext.xml拆解成3个文件,有助于明确配置的作用。
applicationContext.xml 内容如下:
- <?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:context="http://www.springframework.org/schema/context"
- 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">
- <!-- Example of SAF2 action instantiated by Spring -->
- <bean id="helloWorldAction" class="com.ceair.app.HelloWorldAction" />
- <bean id="userAction" class="com.ceair.app.action.UserAction"/>
- <context:annotation-config/>
- <context:component-scan base-package="com.ceair"/>
- </beans>
注意点: 1、12-13行(<context:annotation-config/> 和<context:component-scan base-
package
=
"com.ceair"
/> )的加入是因为在只有的单元测试类中要用到一些注解,如@Autowire
2、因为12-13行的加入,所以要增加第4行(xmlns:context=
"http://www.springframework.org/schema/context")和第8行(http:
//www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
)的声明。
applicationContext-dao.xml内容如下:
- <?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:jee="http://www.springframework.org/schema/jee"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
- <bean id="userDao" class="com.ceair.app.dao.hibernate.GenericDaoHibernate">
- <constructor-arg value="com.ceair.app.model.User"/>
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- </beans>
applicationContext-hibernate.xml 内容如下:
- <?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:jee="http://www.springframework.org/schema/jee"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
- <!-- For settings and future properties files -->
- <bean id="propertyConfigurer"
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:jdbc.properties</value>
- </list>
- </property>
- </bean>
- <!--
- DriverManagerDataSource不具备连接池的功能 <bean id="dataSource"
- class="org.springframework.jdbc.datasource.DriverManagerDataSource"
- destroy-method="close"> <property name="driverClassName"
- value="${hibernate.connection.driver_class}"/> <property name="url"
- value="${hibernate.connection.url}"/> <property name="username"
- value="${hibernate.connection.username}"/> <property name="password"
- value="${hibernate.connection.password}"/> <property name="maxActive"
- value="100"/> <property name="maxWait" value="1000"/> <property
- name="poolPreparedStatements" value="true"/> <property
- name="defaultAutoCommit" value="true"/> </bean>
- -->
- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
- destroy-method="close">
- <property name="driverClass">
- <value>${hibernate.connection.driver_class}</value>
- </property>
- <property name="jdbcUrl">
- <value>${hibernate.connection.url}</value>
- </property>
- <property name="user">
- <value>${hibernate.connection.username}</value>
- </property>
- <property name="password">
- <value>${hibernate.connection.password}</value>
- </property>
- <!--连接池中保留的最小连接数。-->
- <property name="minPoolSize">
- <value>5</value>
- </property>
- <!--连接池中保留的最大连接数。Default: 15 -->
- <property name="maxPoolSize">
- <value>30</value>
- </property>
- <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
- <property name="initialPoolSize">
- <value>10</value>
- </property>
- <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
- <property name="maxIdleTime">
- <value>60</value>
- </property>
- <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
- <property name="acquireIncrement">
- <value>5</value>
- </property>
- <!--
- JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements
- 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。
- 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0
- -->
- <property name="maxStatements">
- <value>150</value>
- </property>
- <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->
- <property name="idleConnectionTestPeriod">
- <value>60</value>
- </property>
- <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
- <property name="acquireRetryAttempts">
- <value>30</value>
- </property>
- <!--
- 获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效
- 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试
- 获取连接失败后该数据源将申明已断开并永久关闭。Default: false
- -->
- <property name="breakAfterAcquireFailure">
- <value>true</value>
- </property>
- <!--
- 因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的
- 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable
- 等方法来提升连接测试的性能。Default: false
- -->
- <property name="testConnectionOnCheckout">
- <value>false</value>
- </property>
- </bean>
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
- <property name="dataSource" ref="dataSource" />
- <property name="configLocation" value="classpath:hibernate.cfg.xml" />
- <property name="hibernateProperties">
- <props>
- <prop key="hibernate.dialect">${hibernate.dialect}</prop>
- <prop key="hibernate.cache.use_second_level_cache">false</prop>
- <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
- <prop key="show_sql">true</prop>
- </props>
- </property>
- </bean>
- <bean id="transactionManager"
- class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory" ref="sessionFactory" />
- </bean>
- </beans>
2、创建单元测试类
在src\test\java\com\ceair\app创建UserDaoTest.java,代码如下:
- package com.ceair.app;
- import org.junit.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.ceair.app.dao.BaseDaoTestCase;
- import com.ceair.app.dao.GenericDao;
- import com.ceair.app.model.User;
- public class UserDaoTest extends BaseDaoTestCase {
- @Autowired
- private GenericDao<User, Long> userDao;
- @Test
- public void testUserById() throws Exception {
- User people = userDao.get(new Long(-2));
- assertEquals("管理员", people.getName());
- }
- @Test
- public void testAddAndRemovePerson() throws Exception {
- User person = new User();
- person.setId(new Long(3));
- person.setName("陈小林");
- person = userDao.save(person);
- flush();
- person = userDao.get(person.getId());
- assertEquals("陈小林", person.getName());
- assertNotNull(person.getId());
- person.setName("陈小");
- flush();
- person = userDao.get(person.getId());
- assertEquals("陈小", person.getName());
- assertNotNull(person.getId());
- }
- }
注意:1、测试数据有的来自于sample-data.xml如21行(User people = userDao.get(
new
Long(-
2
)); )主键为-2的对象。
以上工作全部完成后,打开命令行进入项目目录运行mvn test就可以运行单元测试。
如果我们除了CRUD功能还需要其它方法呢?我们接下去将演示自定义接口和声明式事务
1、在src\main\java\com\ceair\app\dao下创建UserDao.java,代码如下:
- package com.ceair.app.dao;
- import java.util.List;
- import org.hibernate.criterion.DetachedCriteria;
- import com.ceair.app.model.User;
- public interface UserDao extends GenericDao<User, Long> {
- public List<User> findByCrteria(DetachedCriteria crteria);
- public void changeName(String id,String newName) throws Exception;
- }
2、在src\main\java\com\ceair\app\dao\hibernate下创建UserDaoHibernate.java,代码如下:
- package com.ceair.app.dao.hibernate;
- import java.util.List;
- import org.hibernate.criterion.DetachedCriteria;
- import org.hibernate.criterion.Restrictions;
- import org.springframework.transaction.annotation.Isolation;
- import org.springframework.transaction.annotation.Propagation;
- import org.springframework.transaction.annotation.Transactional;
- import com.ceair.app.dao.UserDao;
- import com.ceair.app.model.User;
- public class UserDaoHibernate extends GenericDaoHibernate<User, Long> implements UserDao {
- public UserDaoHibernate() {
- super(User.class);
- }
- @SuppressWarnings("unchecked")
- //@Transactional(readOnly = true, propagation=Propagation.SUPPORTS) 执行读操作的时候,避免使用@Transactional,如果要使用,那就如此所示用法
- public List<User> findByCrteria(DetachedCriteria crteria) {
- return getHibernateTemplate().findByCriteria(crteria);
- }
- /*
- * Required : 如果在一个事务中调用,就将该方法加到此事务中,如果没有启动事务,就创建新事务
- *
- * RequiredNew : 不管当前有没有事务,都启动新事务,如果有,会被挂起,直到此方法结束
- *
- * NotSupported : 不能在事务中执行此方法,如果有事务,会被挂起,直到此方法结束
- *
- * Supports : 如果有当前事务,此方法回加到当前事务,如果没有,容器不会启动新事务
- *
- * Mandatory : 必须在事务中执行此方法,否则会抛出异常 : TransactionRequiredException
- *
- * Never : 必须不在事务中调用此方法,否则抛出RemoteException(远程调用)或EJBException(本地调用)
- *
- */
- @Transactional(
- propagation = Propagation.REQUIRED,
- isolation = Isolation.DEFAULT,//锁级别
- rollbackFor = Exception.class
- )
- public void changeName(String id, String newName) throws Exception {
- DetachedCriteria crteria = DetachedCriteria.forClass(User.class);
- crteria.add(Restrictions.eq("id", new Long(id)));
- List<User> userList = getHibernateTemplate().findByCriteria(crteria);
- User user = userList.get(0);
- user.setName(newName);
- getHibernateTemplate().update(user);
- // throw new Exception();//rollback
- }
- }
注意:1、去掉55行(
throw new Exception();//rollback
)的注释,会回滚数据库操作。
3、修改\src\main\resources下的applicationContext.xml文件,修改后文件内容如下:
- <?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:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- <!-- Example of SAF2 action instantiated by Spring -->
- <bean id="helloWorldAction" class="com.ceair.app.HelloWorldAction" />
- <bean id="userAction" class="com.ceair.app.action.UserAction"/>
- <context:annotation-config/>
- <context:component-scan base-package="com.ceair"/>
- <tx:annotation-driven transaction-manager="transactionManager"/>
- </beans>
注意:1、增加了13行(
<context:annotation-config/>
)声明(支持SPRING事务标注),增加第5(
xmlns:tx
=
"http://www.springframework.org/schema/tx"),第8( http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd )行的命名空间声明。
4、修改\src\main\resources下的applicationContext-dao.xml文件,修改后文件内容如下:
- <?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:jee="http://www.springframework.org/schema/jee"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
- <bean id="userCustomDao" class="com.ceair.app.dao.hibernate.UserDaoHibernate" >
- <property name="sessionFactory" ref="sessionFactory"/>
- </bean>
- </beans>
注意:1、增加7-8行,把原来的Bean userDao删除了
5、修改src\test\java\com\ceair\app下的UserDaoTest.java,修改后内容如下:
- package com.ceair.app;
- import org.junit.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.ceair.app.dao.BaseDaoTestCase;
- import com.ceair.app.dao.UserDao;
- import com.ceair.app.model.User;
- public class UserDaoTest extends BaseDaoTestCase {
- @Autowired
- private UserDao userCustomDao;
- @Test
- public void testUserById() throws Exception {
- User people = userCustomDao.get(new Long(-2));
- assertEquals("管理员", people.getName());
- }
- @Test
- public void testAddAndRemovePerson() throws Exception {
- User person = new User();
- person.setId(new Long(3));
- person.setName("陈小林");
- person = userCustomDao.save(person);
- flush();
- person = userCustomDao.get(person.getId());
- assertEquals("陈小林", person.getName());
- assertNotNull(person.getId());
- person.setName("陈小");
- flush();
- person = userCustomDao.get(person.getId());
- assertEquals("陈小", person.getName());
- assertNotNull(person.getId());
- log.debug("removing person...");
- }
- }
6、在src\test\java\com\ceair\app下创建UserCustomDaoTest.java,代码内容如下:
- package com.ceair.app;
- import java.util.List;
- import org.hibernate.criterion.DetachedCriteria;
- import org.hibernate.criterion.Restrictions;
- import org.junit.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.ceair.app.dao.BaseDaoTestCase;
- import com.ceair.app.dao.UserDao;
- import com.ceair.app.model.User;
- public class UserCustomDaoTest extends BaseDaoTestCase {
- @Autowired
- private UserDao userCustomDao;
- @Test
- public void testFindByCrteria() throws Exception {
- DetachedCriteria crteria=DetachedCriteria.forClass(User.class);
- crteria.add(Restrictions.eq("name", "管理员"));
- List<User> userList=userCustomDao.findByCrteria(crteria);
- assertEquals("管理员", userList.get(0).getName());
- assertEquals(new Long(-2), userList.get(0).getId());
- }
- @Test
- public void testChangeName() throws Exception {
- userCustomDao.changeName("-2", "新管理员");
- flush();
- User people = userCustomDao.get(new Long(-2));
- assertEquals("新管理员", people.getName());
- }
- }
注意:1、事务测试前可以把BaseDaoTestCase.java59行(不回滚测试产生的数据)和UserDaoHibernate .java55行(抛出异常,回滚事务)和的注释去除,然后去数据库中查看是否更改名字成功。
以上工作全部完成后,打开命令行进入项目目录运行mvn test就可以运行单元测试。
关于事务的深入研究可以查看
http://www.ibm.com/developerworks/cn/java/j-ts1.html
转载于:https://blog.51cto.com/tangjj/349226