spring+hibernate集成进行编码测试

建一个服务层的类,先定义它的接口

PersonService.java
package cn.itcast.service; 
 
import java.util.List; 
 
import cn.itcast.bean.Person; 
 
public interface PersonService { 
 
    public void save(Person person); 
 
    public void update(Person person); 
 
    public Person getPerson(Integer personid); 
 
    public void delete(Integer personid); 
 
    public List<Person> getPersons(); 
 
}
package cn.itcast.service;<br/><br/>import java.util.List;<br/><br/>import cn.itcast.bean.Person;<br/><br/>public interface PersonService {<br/><br/> public void save(Person person);<br/><br/> public void update(Person person);<br/><br/> public Person getPerson(Integer personid);<br/><br/> public void delete(Integer personid);<br/><br/> public List<Person> getPersons();<br/><br/>}


PersonServiceBean.java
package cn.itcast.service.impl; 
 
import java.util.List; 
 
import javax.annotation.Resource; 
 
import org.hibernate.SessionFactory; 
import org.springframework.transaction.annotation.Propagation; 
import org.springframework.transaction.annotation.Transactional; 
 
import cn.itcast.bean.Person; 
import cn.itcast.service.PersonService; 
 
@Transactional 
public class PersonServiceBean implements PersonService { 
    /*       session是通过sessionFactory得到的,目前sessionFactory已经在Spring容器里面被管理了,采用依赖注入可以       得到sessionFactory,在beans.xml里有这一句<context:annotation-config/>,说明可以采用注解的方式注入       @Resource默认是按名称去匹配的,当对象注入到字段里面上去之后呢,我们就可以通过这个字段来得到session了。       */ 
    @Resource 
    private SessionFactory sessionFactory; 
 
    //方法执行前打开事务 
    public void save(Person person) { 
        /*           在得到session后,有一点要注意的是以前得到session是通过sessionFactory.openSession,在这里要注意,因为Spring          自动帮我们管理事务,也就是说它会自动帮我们管理session这个对象,这时候我们只需要调用getCurrentSession这个方法          从Spring容器里得到当前被Spring容器管理的session,而不能采用openSession,如果采用的是openSession的话,          你打开的session是不受Spring容器管理的,也就是说Spring容器无法对你打开的session进行事务打开,提交。。          所以要用getCurrentSession方法取得容器中被管理的那个session          */ 
        sessionFactory.getCurrentSession().persist(person); 
        /*           不建议使用save方法,persist也是JPA规范里面规定的一个方法,也是用于保存实体的,这           方法名字上更合理些,因为叫"持久化"比叫"保存"更合理些,实际上两个方法的作用是一样的           */ 
    } 
    //方法执行后结束事务 
 
    public void update(Person person) { 
        /*            做更新一般是这样的,当你的对象变成游离状态的对象的时候,这时候才需要对它进行更新。            如果这对象正处于被容器session管理,tuo管状态的时候,我们不需要调用更新方法也能对它进行更新(调用set方法就行了)            一般update里面的对象是处于游离状态的           */ 
        sessionFactory.getCurrentSession().merge(person); 
        /*            不建议大家用update,merge方法跟JPA里面的方法是对应起来的,同样也是用于把对游离对象的更新同步到数据库,            返回的是一个tuo管状态的对象           */ 
    } 
 
    //一般情况下,如果只是获取数据的话,是不需要开启事务的,因为开事务会对应用的性能产生影响的 
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) 
    public Person getPerson(Integer personid) { 
        return (Person) sessionFactory.getCurrentSession().get(Person.class, 
                personid); 
    } 
 
    public void delete(Integer personid) { 
        sessionFactory.getCurrentSession().delete( 
                        sessionFactory.getCurrentSession().load(Person.class,personid)); 
        /*           删除的时候,要求一个实体对象做参数,实体对象怎么获取呢?可以采用get获取,也可以采用load获取。           这里建议大家采用load,load的性能比get好一些,因为get方法有个数据装配的过程,就是说把数据从数据库           查询出来后,再把数据封装到实体对象里面去。load方法就没有数据封装的过程,相对效率高很多           */ 
    } 
 
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true) 
    @SuppressWarnings("unchecked") 
    public List<Person> getPersons() { 
        return sessionFactory.getCurrentSession().createQuery("from Person").list(); 
    } 
 
}
package cn.itcast.service.impl;<br/><br/>import java.util.List;<br/><br/>import javax.annotation.Resource;<br/><br/>import org.hibernate.SessionFactory;<br/>import org.springframework.transaction.annotation.Propagation;<br/>import org.springframework.transaction.annotation.Transactional;<br/><br/>import cn.itcast.bean.Person;<br/>import cn.itcast.service.PersonService;<br/><br/>@Transactional<br/>public class PersonServiceBean implements PersonService {<br/> /*<br/> session是通过sessionFactory得到的,目前sessionFactory已经在Spring容器里面被管理了,采用依赖注入可以<br/> 得到sessionFactory,在beans.xml里有这一句<context:annotation-config/>,说明可以采用注解的方式注入<br/> @Resource默认是按名称去匹配的,当对象注入到字段里面上去之后呢,我们就可以通过这个字段来得到session了。<br/> */<br/> @Resource<br/> private SessionFactory sessionFactory;<br/><br/> //方法执行前打开事务<br/> public void save(Person person) {<br/> /*<br/> 在得到session后,有一点要注意的是以前得到session是通过sessionFactory.openSession,在这里要注意,因为Spring<br/> 自动帮我们管理事务,也就是说它会自动帮我们管理session这个对象,这时候我们只需要调用getCurrentSession这个方法<br/> 从Spring容器里得到当前被Spring容器管理的session,而不能采用openSession,如果采用的是openSession的话,<br/> 你打开的session是不受Spring容器管理的,也就是说Spring容器无法对你打开的session进行事务打开,提交。。<br/> 所以要用getCurrentSession方法取得容器中被管理的那个session<br/> */<br/> sessionFactory.getCurrentSession().persist(person);<br/> /*<br/> 不建议使用save方法,persist也是JPA规范里面规定的一个方法,也是用于保存实体的,这<br/> 方法名字上更合理些,因为叫"持久化"比叫"保存"更合理些,实际上两个方法的作用是一样的<br/> */<br/> }<br/> //方法执行后结束事务<br/><br/> public void update(Person person) {<br/> /*<br/> 做更新一般是这样的,当你的对象变成游离状态的对象的时候,这时候才需要对它进行更新。<br/> 如果这对象正处于被容器session管理,tuo管状态的时候,我们不需要调用更新方法也能对它进行更新(调用set方法就行了)<br/> 一般update里面的对象是处于游离状态的<br/> */<br/> sessionFactory.getCurrentSession().merge(person);<br/> /*<br/> 不建议大家用update,merge方法跟JPA里面的方法是对应起来的,同样也是用于把对游离对象的更新同步到数据库,<br/> 返回的是一个tuo管状态的对象<br/> */<br/> }<br/><br/> //一般情况下,如果只是获取数据的话,是不需要开启事务的,因为开事务会对应用的性能产生影响的<br/> @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)<br/> public Person getPerson(Integer personid) {<br/> return (Person) sessionFactory.getCurrentSession().get(Person.class,<br/> personid);<br/> }<br/><br/> public void delete(Integer personid) {<br/> sessionFactory.getCurrentSession().delete(<br/> sessionFactory.getCurrentSession().load(Person.class,personid));<br/> /*<br/> 删除的时候,要求一个实体对象做参数,实体对象怎么获取呢?可以采用get获取,也可以采用load获取。<br/> 这里建议大家采用load,load的性能比get好一些,因为get方法有个数据装配的过程,就是说把数据从数据库<br/> 查询出来后,再把数据封装到实体对象里面去。load方法就没有数据封装的过程,相对效率高很多<br/> */<br/> }<br/><br/> @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)<br/> @SuppressWarnings("unchecked")<br/> public List<Person> getPersons() {<br/> return sessionFactory.getCurrentSession().createQuery("from Person").list();<br/> }<br/><br/>}

开发完业务bean了,每当开发完业务bean,先不要急着跟控制层进行集成,也就是说 CC霜排行榜不要在控制层急于使用业务层对象。
开发完业务层后,需要对业务方法进行单元测试,这是我们在开发过程中需要养成的比较好的习惯。

Person.java
package cn.itcast.bean; 
 
public class Person { 
    private Integer id; 
    private String name; 
 
    public Person() { 
    } 
 
    public Person(String name) { 
        this.name = 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; 
    } 
}
package cn.itcast.bean;<br/><br/>public class Person {<br/> private Integer id;<br/> private String name;<br/><br/> public Person() {<br/> }<br/><br/> public Person(String name) {<br/> this.name = name;<br/> }<br/><br/> public Integer getId() {<br/> return id;<br/> }<br/><br/> public void setId(Integer id) {<br/> this.id = id;<br/> }<br/><br/> public String getName() {<br/> return name;<br/> }<br/><br/> public void setName(String name) {<br/> this.name = name;<br/> }<br/>}
<?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:aop="http://www.springframework.org/schema/aop"
       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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
     <context:annotation-config/>
     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springjdbc?useUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="456"/>
         <!-- 连接池启动时的初始值 -->
         <property name="initialSize" value="1"/>
         <!-- 连接池的最大值 -->
         <property name="maxActive" value="500"/>
         <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
         <property name="maxIdle" value="2"/>
         <!--  最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
         <property name="minIdle" value="1"/>
      </bean>

    <!--通过这个配置就可以定义一个sessionFactory,这个对象在容器里面只存在一个,它是一个单例的形式-->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
         <property name="dataSource" ref="dataSource"/> <!--数据源-->
         <property name="mappingResources">
            <list>
              <value>cn/itcast/bean/Person.hbm.xml</value><!--实体bean的映射元数据-->
            </list>
         </property>
         <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
                hibernate.hbm2ddl.auto=update<!--代表要不要根据映射元数据来生成数据库表结构-->
                hibernate.show_sql=false <!--是否打印Hibernate执行的sql-->
                hibernate.format_sql=false <!--是否要对它进行格式化-->
                <!--这两个主要在测试阶段比较有用-->
              </value>
         </property>
    </bean>

    <!--配置事务管理,使用的事务管理器是Spring为我们提供的,针对Hibernate的一个事务管理器-->
    <!--只要是通过sessionFactory对象创建的session都会纳入到这个事务管理器中-->
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!--配置事务采用的申明方式,事务申明的方式有两种:1种是基于XML的方式,1种是基于注解的方式
    ,这里是使用注解方式来申明事务-->
    <!--这段打开了对@Transaction注解的支持,这里用到的事务管理器就是前面提到的txManager-->
    <tx:annotation-driven transaction-manager="txManager"/>

    <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?><br/><beans xmlns="http://www.springframework.org/schema/beans"<br/> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br/> xmlns:context="http://www.springframework.org/schema/context"<br/> xmlns:aop="http://www.springframework.org/schema/aop"<br/> xmlns:tx="http://www.springframework.org/schema/tx"<br/> xsi:schemaLocation="http://www.springframework.org/schema/beans<br/> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br/> http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd<br/> http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br/> http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><br/> <context:annotation-config/><br/> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><br/> <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/><br/> <property name="url" value="jdbc:mysql://localhost:3306/springjdbc?useUnicode=true&characterEncoding=UTF-8"/><br/> <property name="username" value="root"/><br/> <property name="password" value="456"/><br/> <!-- 连接池启动时的初始值 --><br/> <property name="initialSize" value="1"/><br/> <!-- 连接池的最大值 --><br/> <property name="maxActive" value="500"/><br/> <!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 --><br/> <property name="maxIdle" value="2"/><br/> <!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 --><br/> <property name="minIdle" value="1"/><br/> </bean><br/><br/> <!--通过这个配置就可以定义一个sessionFactory,这个对象在容器里面只存在一个,它是一个单例的形式--><br/> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><br/> <property name="dataSource" ref="dataSource"/> <!--数据源--><br/> <property name="mappingResources"><br/> <list><br/> <value>cn/itcast/bean/Person.hbm.xml</value><!--实体bean的映射元数据--><br/> </list><br/> </property><br/> <property name="hibernateProperties"><br/> <value><br/> hibernate.dialect=org.hibernate.dialect.MySQL5Dialect<br/> hibernate.hbm2ddl.auto=update<!--代表要不要根据映射元数据来生成数据库表结构--><br/> hibernate.show_sql=false <!--是否打印Hibernate执行的sql--><br/> hibernate.format_sql=false <!--是否要对它进行格式化--><br/> <!--这两个主要在测试阶段比较有用--><br/> </value><br/> </property><br/> </bean><br/><br/> <!--配置事务管理,使用的事务管理器是Spring为我们提供的,针对Hibernate的一个事务管理器--><br/> <!--只要是通过sessionFactory对象创建的session都会纳入到这个事务管理器中--><br/> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><br/> <property name="sessionFactory" ref="sessionFactory"/><br/> </bean><br/><br/> <!--配置事务采用的申明方式,事务申明的方式有两种:1种是基于XML的方式,1种是基于注解的方式<br/> ,这里是使用注解方式来申明事务--><br/> <!--这段打开了对@Transaction注解的支持,这里用到的事务管理器就是前面提到的txManager--><br/> <tx:annotation-driven transaction-manager="txManager"/><br/><br/> <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"/><br/></beans>

打开数据库,如果存在person表的话,就把它删掉,因为在beans.xml里的 Hibernate属性配置,配置成hibernate.hbm2ddl.auto=update,所以它会自动的根据我们配置的元数据来生成数据库表。

PersonServiceTest.java 
package junit.test; 
 
import java.util.List; 
 
import org.junit.BeforeClass; 
import org.junit.Test; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
 
import cn.itcast.bean.Person; 
import cn.itcast.service.PersonService; 
 
public class PersonServiceTest { 
    private static PersonService personService; 
 
    @BeforeClass 
    //这个方法是在当单元测试PersonServiceTest实例被构建出来后就会执行 
    //可以在这个方法里面做一些初始化的操作 
    public static void setUpBeforeClass() throws Exception { 
        try { 
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); 
            personService = (PersonService)applicationContext.getBean("personService"); 
        } catch (RuntimeException e) { 
            e.printStackTrace(); 
        } 
    } 
 
    @Test 
    public void testSave() { 
        personService.save(new Person("小张")); 
    } 
 
    @Test 
    public void testUpdate() { 
        Person person = personService.getPerson(1); 
        //.... 
        person.setName("小丽"); 
        personService.update(person); 
    } 
 
    @Test 
    public void testGetPerson() { 
        Person person = personService.getPerson(1); 
        System.out.println(person.getName()); 
    } 
 
    @Test 
    public void testDelete() { 
        personService.delete(1); 
    } 
 
    @Test 
    public void testGetPersons() { 
        List<Person> persons = personService.getPersons(); 
        for(Person person : persons){ 
            System.out.println(person.getName()); 
        } 
    } 
 
}
PersonServiceTest.java<br/>package junit.test;<br/><br/>import java.util.List;<br/><br/>import org.junit.BeforeClass;<br/>import org.junit.Test;<br/>import org.springframework.context.ApplicationContext;<br/>import org.springframework.context.support.ClassPathXmlApplicationContext;<br/><br/>import cn.itcast.bean.Person;<br/>import cn.itcast.service.PersonService;<br/><br/>public class PersonServiceTest {<br/> private static PersonService personService;<br/><br/> @BeforeClass<br/> //这个方法是在当单元测试PersonServiceTest实例被构建出来后就会执行<br/> //可以在这个方法里面做一些初始化的操作<br/> public static void setUpBeforeClass() throws Exception {<br/> try {<br/> ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");<br/> personService = (PersonService)applicationContext.getBean("personService");<br/> } catch (RuntimeException e) {<br/> e.printStackTrace();<br/> }<br/> }<br/><br/> @Test<br/> public void testSave() {<br/> personService.save(new Person("小张"));<br/> }<br/><br/> @Test<br/> public void testUpdate() {<br/> Person person = personService.getPerson(1);<br/> //....<br/> person.setName("小丽");<br/> personService.update(person);<br/> }<br/><br/> @Test<br/> public void testGetPerson() {<br/> Person person = personService.getPerson(1);<br/> System.out.println(person.getName());<br/> }<br/><br/> @Test<br/> public void testDelete() {<br/> personService.delete(1);<br/> }<br/><br/> @Test<br/> public void testGetPersons() {<br/> List<Person> persons = personService.getPersons();<br/> for(Person person : persons){<br/> System.out.println(person.getName());<br/> }<br/> }<br/><br/>}

运行单元测试的testSave方法,运行成功,看数据库表,表是生成了,数据也进去了,如图:


运行单元测试的testGetPerson方法,运行成功,控制台输出:
小张

运行单元测试的testUpdate方法,运行成功,数据改变了,如图:



运行单元测试的testGetPersons方法,运行成功,控制台输出:小丽

运行单元测试的testDelete方法,运行成功,数据被删了,如图:



这些业务方法都通过了 Junit单元测试,也代表我们的业务代码编写是正确的。一旦确定我们业务层是没问题的,接下来就要进行Struts的集成了。

你可能感兴趣的:(spring+hibernate集成进行编码测试)