Spring视频学习(十五)集成JPA
1.所需jar包:
使用Myeclipse时,先添加Spring支持,后添加JPA支持,然后Junit测试,最后添加Struts支持。
2.Spring的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: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 "> <!-- 使用手工配置的注解方式来注入bean --> <context:annotation-config></context:annotation-config> <!-- 1.配置Spring集成JPA --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> <property name="persistenceUnitName" value="SpringJPAPU"/> </bean> <!--2.配置Spring针对JPA的事务 --> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!--3.开启事务注解 --> <tx:annotation-driven transaction-manager="txManager"/> <!--以上3个Spring集成JPA的配置,在web项目先添加Spring支持,后添加JPA支持时会自动生成 --> <!-- 配置业务bean --> <bean id="personService" class="com.persia.service.impl.PersonServiceImpl"></bean> <!-- 配置Struts的action --> <bean name="/person/list" class="com.persia.struts.PersonListAction"/> <bean name="/person/manage" class="com.persia.struts.PersonManageAction"/> </beans>
3.业务bean开发:
(1)JPA的配置文件
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="SpringJPAPU" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name = "hibernate.connection.driver_class" value = "com.mysql.jdbc.Driver"/> <property name = "hibernate.connection.url" value = "jdbc:mysql://localhost:3306/test"/> <property name = "hibernate.connection.username" value = "root"/> <property name="hibernate.max_fetch_depth" value="3"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties> </persistence-unit> </persistence>
(2)model和业务层
import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Person implements Serializable{ @Id @GeneratedValue private Integer id; private String name; public Person(){ //必须保留一个无参数的构造函数 } public Person(String string) { this.name=string; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(length=30,nullable=false) public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }
业务bean如下:
import java.util.List; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.hibernate.SessionFactory; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.persia.model.Person; import com.persia.service.IPersonService; @Transactional public class PersonServiceImpl implements IPersonService { //注解得到一个em对象,主要是由Spring容器从em工厂里获得。 @PersistenceContext EntityManager em; public void save(Person person){ em.persist(person); } public void update(Person person){ em.merge(person); } public void delete(Integer id){ em.remove(em.getReference(Person.class, id)); } @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) public Person getPerson(Integer id){ return em.find(Person.class, id); } @SuppressWarnings("unchecked") @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) public List<Person> getPersons(){ return em.createQuery("select o from Person o").getResultList(); } }
(3)Junit测试
package junit.test; import static org.junit.Assert.*; import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.persia.model.Person; import com.persia.service.IPersonService; public class IPersonServiceTest { private static IPersonService ps; @BeforeClass public static void setUpBeforeClass() throws Exception { try { ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); ps=(IPersonService) ctx.getBean("personService"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } //@Test public void testSave() { ps.save(new Person("JPA")); } //@Test public void testUpdate() { Person p=ps.getPerson(13); p.setName("linda"); ps.update(p); } //@Test public void testGetPerson() { System.out.println(ps.getPerson(7).getName()); try { System.out.println("请在15秒之内关闭数据库"); Thread.sleep(15*1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("从缓存获取:"+ps.getPerson(7).getName()); } //@Test public void testDelete() { ps.delete(11); } @Test public void testGetPersons() { List<Person> ls=ps.getPersons(); for(Person p:ls){ System.out.println(p.getName()); } } }
4、集成Struts
web的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!--1.指定spring的配置文件,默认从web的根目录开始查找,可以通过spring提供的classpath前缀来配置从类路径开始查找 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--2.对Spring容器进行实例化 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--以上 2个步骤即实现了在web容器中实例化spring容器的配置,实例化后放到servletContext里面(Application级别)--> <!--以下是由Spring提供的filter来解决Struts乱码问题 --> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 解决乱码 --> <!-- 解决 JPA因entityManager关闭而导致的延迟加载例外问题--> <filter> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 解决延迟例外问题 --> <!--下面是集成Struts的配置--> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- Struts的配置 --> </web-app>
Struts的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"> <struts-config> <form-beans> <form-bean name="personForm" type="com.persia.struts.formbean.PersonForm"/> </form-beans> <action-mappings> <action path="/person/list" validate="false"> <forward name="list" path="/WEB-INF/page/personlist.jsp"/> </action> <action path="/person/manage" parameter="method" name="personForm" scope="request" validate="false"> <forward name="message" path="/WEB-INF/page/message.jsp"/> </action> </action-mappings> <!--定义Spring的请求处理器,来根据action的path属性到Spring容器里面寻找这个bean,若找到了则用这个bean来处理用户的请求--> <controller> <set-property property="processorClass" value="org.springframework.web.struts.DelegatingRequestProcessor"/> </controller> <!--配置完Spring的请求处理器后,去掉action的type属性和值,因为已经交给Spring容器来处理(可选)当Spring处理器找不到该bean时,才会使用Struts的action--> <message-resources parameter="com.persia.struts.ApplicationResources" /> </struts-config>
Struts的action使用Spring注入业务bean:
import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.DispatchAction; import com.persia.model.Person; import com.persia.service.IPersonService; import com.persia.struts.formbean.PersonForm; public class PersonManageAction extends DispatchAction { @Resource IPersonService ps; public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { PersonForm f=(PersonForm)form; ps.save(new Person(f.getName())); request.setAttribute("message", "添加成功"); return mapping.findForward("message"); } }