Spring-3.2.0+Struts-2.3.4+JPA2.0 整合首先我们要引入整合需要的包,所需要的包如下图:
这里需要注意与JPA的整合需要加入hibernate-entitymanager-4.1.6.Final.jar这个包,另外用Eclipse(MyEclipse)新建项目时不需要引入J2EE的相关jar包(MyEclipse新建时会自动引入,我们可以手动删除,如下图),因为Hibernate已经集成了JPA的相关jar包,jar包有冲突或过少都会整合失败.
引入相关的jar后我们要在classpath(src)下新建META-INF/persistence.xml(这个是固定的),这里我们使用MySQL数据库进行演示,其内容如下:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" 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_2_0.xsd"> <persistence-unit name="SHOPPINGJPA" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!--配置Hibernate方言 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <!--配置数据库驱动 --> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <!--配置数据库用户名 --> <property name="hibernate.connection.username" value="root" /> <!--配置数据库密码 --> <property name="hibernate.connection.password" value="619100" /> <!--配置数据库url --> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/shopping" /> <!--设置外连接抓取树的最大深度 --> <property name="hibernate.max_fetch_depth" value="3" /> <!--自动输出schema创建DDL语句 --> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="javax.persistence.validation.mode" value="none"/> </properties> </persistence-unit> </persistence>
然后我们新建在classpath(src)下log4j.properties日志文件:
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file hibernate.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=D:/Project/Shopping/shop.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=warn, stdout #log4j.logger.gd.hz.oa=debug
在新建Spring配置文件(在classpath(src)下)beans.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-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="gd.hz.shopping" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="SHOPPINGJPA" />
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 对@Transactional这个注解进行的驱动,
这是基于注解的方式使用事务配置声明,这样在具体应用中可以指定对哪些方法使用事务。 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="bussinessService"
expression="execution(public
* gd.hz.shopping.service.*.*(..))" />
<aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" />
</aop:config>
-->
</beans>
这里我们需要注意,事务的声明有编程式和声明式,注释的为声明式事务管理,可提供统一的事物管理,这里在我们使用编程式声明这样可以更灵活的管理我们的事务.
然后我们新建一下我们的struts.xml(在classpath(src)下)文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.i18n.encoding" value="UTF-8" /> </struts>
配置一下我们的web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:beans.xml</param-value> </context-param> <!-- 配置spring监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 编码过滤器 --> <filter> <filter-name>encodingFilter</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>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- 声明session在view层关闭 --> <filter> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class> <init-param> <param-name>entityManagerFactoryBeanName</param-name> <param-value>entityManagerFactory</param-value> </init-param> </filter> <filter-mapping> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 声明使用struts2 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>InitParamServlet</servlet-name> <servlet-class>gd.hz.shopping.servlet.InitParamServlet</servlet-class> <!-- 配置商品类别列显示条数 --> <init-param> <param-name>productTypePageSize</param-name> <param-value>20</param-value> </init-param> <load-on-startup>5</load-on-startup> </servlet> </web-app>
整合后的目录结构如下:
编写我们的测试程序:
编写实体类:
package gd.hz.shopping.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class ProductType {
/**
* 类别ID
*/
private Integer id ;
/**
* 用户名称
*/
private String name ;
/**
* 备注,用于搜索引擎
*/
private String note ;
/**
* 是否可见
*/
private Boolean visible = true ;
@Id
@GeneratedValue
@Column(name="productId")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(nullable=false , length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(length=128)
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@Column(nullable=false)
public Boolean getVisible() {
return visible;
}
public void setVisible(Boolean visible) {
this.visible = visible;
}
}
编写Dao接口:
package gd.hz.shopping.dao;
public interface ProductTypeDao {
/**
* 查询实体
* @param entityClass
* @param entityId
* @return
*/
public <T> T select(Class<T> entityClass , Object entityId) ;
}
编写Dao实现:
package gd.hz.shopping.dao.impl;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import gd.hz.shopping.dao.ProductTypeDao;
/**
* 商品类别DAO层
* @author Administrator
*
*/
@Repository("productTypeDao")
@Transactional
public class ProductTypeDaoImpl implements ProductTypeDao {
protected EntityManager entityManager ;
@PersistenceContext
protected void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
/**
* 根据ID查询用户
* readOnly=true 声明为只读
* propagation=Propagation.NOT_SUPPORTED:声明不需要事务,当不需要事务时挂起
*/
@Override
@Transactional(readOnly=true , propagation=Propagation.NOT_SUPPORTED)
public <T> T select(Class<T> entityClass, Object entityId) {
return entityManager.find(entityClass , entityId);
}
}
编写Service接口:
package gd.hz.shopping.service;
public interface ProductTypeService {
public <T> T find(Class<T> entityClass , Object entityId) ;
}
编写Service实现类:
package gd.hz.shopping.service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import gd.hz.shopping.dao.ProductTypeDao;
import gd.hz.shopping.service.ProductTypeService;
@Service("productTypeMnager")
@Transactional
public class ProductTypeServiceImpl implements ProductTypeService {
private ProductTypeDao productTypeDao = null ;
@Resource(name="productTypeDao")
public void setProductTypeDao(ProductTypeDao productTypeDao) {
this.productTypeDao = productTypeDao;
}
@Override
public <T> T find(Class<T> entityClass, Object entityId) {
return productTypeDao.select(entityClass, entityId);
}
}
新建struts控制类:
package gd.hz.shopping.action;
import javax.annotation.Resource;
import gd.hz.shopping.model.ProductType;
import gd.hz.shopping.service.ProductTypeService;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.opensymphony.xwork2.ActionSupport;
@Controller("testAction")
@Scope("prototype")
public class TestAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private ProductTypeService productTypeService = null ;
private ProductType productType = null ;
public ProductType getProductType() {
return productType;
}
public void setProductType(ProductType productType) {
this.productType = productType;
}
@Resource(name="productTypeMnager")
public void setProductTypeService(ProductTypeService productTypeService) {
this.productTypeService = productTypeService;
}
public String index()
{
//查询ID为13的ProductType
productType = productTypeService.find(ProductType.class , 13);
return "index" ;
}
}
新建jsp页面:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'Test.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<%--使用OGNL表达式--%>
您好:<s:property value="productType.name"/><br>
</body>
</html>
重新配置struts.xml文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="true" /> <constant name="struts.i18n.encoding" value="UTF-8" /> <package name="org" namespace="/" extends="struts-default"> <action name="testAction" class="testAction"> <result name="index">/Test.jsp</result> </action> </package> </struts>
输入URL:http://xxx/testAction!index 结果如下: