建一个服务层的类,先定义它的接口
PersonService.java
PersonServiceBean.java
开发完业务bean了,每当开发完业务bean,先不要急着跟控制层进行集成,也就是说 CC霜排行榜不要在控制层急于使用业务层对象。
开发完业务层后,需要对业务方法进行单元测试,这是我们在开发过程中需要养成的比较好的习惯。
Person.java
打开数据库,如果存在person表的话,就把它删掉,因为在beans.xml里的 Hibernate属性配置,配置成hibernate.hbm2ddl.auto=update,所以它会自动的根据我们配置的元数据来生成数据库表。
运行单元测试的testSave方法,运行成功,看数据库表,表是生成了,数据也进去了,如图:
运行单元测试的testGetPerson方法,运行成功,控制台输出:
小张
运行单元测试的testUpdate方法,运行成功,数据改变了,如图:
运行单元测试的testGetPersons方法,运行成功,控制台输出:小丽
运行单元测试的testDelete方法,运行成功,数据被删了,如图:
这些业务方法都通过了 Junit单元测试,也代表我们的业务代码编写是正确的。一旦确定我们业务层是没问题的,接下来就要进行Struts的集成了。
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;
public class PersonServiceBean implements PersonService {
/*
session是通过sessionFactory得到的,目前sessionFactory已经在Spring容器里面被管理了,采用依赖注入可以
得到sessionFactory,在beans.xml里有这一句<context:annotation-config/>,说明可以采用注解的方式注入
@Resource默认是按名称去匹配的,当对象注入到字段里面上去之后呢,我们就可以通过这个字段来得到session了。
*/
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管状态的对象
*/
}
//一般情况下,如果只是获取数据的话,是不需要开启事务的,因为开事务会对应用的性能产生影响的
(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方法就没有数据封装的过程,相对效率高很多
*/
}
(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
("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&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;
//这个方法是在当单元测试PersonServiceTest实例被构建出来后就会执行
//可以在这个方法里面做一些初始化的操作
public static void setUpBeforeClass() throws Exception {
try {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
personService = (PersonService)applicationContext.getBean("personService");
} catch (RuntimeException e) {
e.printStackTrace();
}
}
public void testSave() {
personService.save(new Person("小张"));
}
public void testUpdate() {
Person person = personService.getPerson(1);
//....
person.setName("小丽");
personService.update(person);
}
public void testGetPerson() {
Person person = personService.getPerson(1);
System.out.println(person.getName());
}
public void testDelete() {
personService.delete(1);
}
public void testGetPersons() {
List<Person> persons = personService.getPersons();
for(Person person : persons){
System.out.println(person.getName());
}
}
}
运行单元测试的testSave方法,运行成功,看数据库表,表是生成了,数据也进去了,如图:
运行单元测试的testGetPerson方法,运行成功,控制台输出:
小张
运行单元测试的testUpdate方法,运行成功,数据改变了,如图:
运行单元测试的testGetPersons方法,运行成功,控制台输出:小丽
运行单元测试的testDelete方法,运行成功,数据被删了,如图:
这些业务方法都通过了 Junit单元测试,也代表我们的业务代码编写是正确的。一旦确定我们业务层是没问题的,接下来就要进行Struts的集成了。