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(); 
 
}



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(); 
    } 
 
}


开发完业务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; 
    } 
}

<?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>


打开数据库,如果存在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()); 
        } 
    } 
 
}


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


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

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



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

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



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值