ssh整合,从hibernate那个版本开始需要open session in view 才能开启事务?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ssh整合,从hibernate那个版本开始需要open session in view 才能开启事务?相关的知识,希望对你有一定的参考价值。
事务才能生效?
参考技术A 如果ssh整合,你只需要在applicationContext.xml里配置事务,然后在要使用事务的地方标注相应的事务注解标签就可以了。并不需要手动开启事务和关闭事务,也不需要使用openSession来获得session,可以使用getcurrentsession来获取session,该session对象会在事务自动提交之后自动关闭。如果你不使用spring,那么你需要自己控制懒加载和session的关闭。
希望回答对你有用。 参考技术B Hibernate 3.3本回答被提问者采纳
SSH整合简单例子
说明:简单SSH整合,struts版本2.3.32,spring版本3.2.9,hibernate版本3.6.10
一、开发步骤
1 引jar包,创建用户library。使用的包和之前博文相同,可以参考spring和hibernate整合,事务管理,struts和spring整合
jar包如下
//struts_core Struts2.3.32core\\commons-fileupload-1.3.2.jar Struts2.3.32core\\commons-io-2.2.jar Struts2.3.32core\\commons-lang3-3.2.jar Struts2.3.32core\\freemarker-2.3.22.jar Struts2.3.32core\\javassist-3.11.0.GA.jar Struts2.3.32core\\ognl-3.0.19.jar Struts2.3.32core\\struts2-core-2.3.32.jar Struts2.3.32core\\xwork-core-2.3.32.jar //spring_core spring3.2.9core\\commons-logging-1.2.jar spring3.2.9core\\spring-beans-3.2.9.RELEASE.jar spring3.2.9core\\spring-context-3.2.9.RELEASE.jar spring3.2.9core\\spring-core-3.2.9.RELEASE.jar spring3.2.9core\\spring-expression-3.2.9.RELEASE.jar //struts_spring_web struts-spring-web\\struts2-spring-plugin-2.3.32.jar struts-spring-web\\spring-web-3.2.9.RELEASE.jar struts-spring-web\\spring-webmvc-3.2.9.RELEASE.jar //hibernate_core hibernate3.6core\\antlr-2.7.6.jar hibernate3.6core\\commons-collections-3.1.jar hibernate3.6core\\dom4j-1.6.1.jar hibernate3.6core\\hibernate3.jar hibernate3.6core\\hibernate-jpa-2.0-api-1.0.1.Final.jar hibernate3.6core\\javassist-3.12.0.GA.jar hibernate3.6core\\jta-1.1.jar hibernate3.6core\\slf4j-api-1.6.1.jar hibernate3.6core\\slf4j-nop-1.7.25.jar //DB_connector DB-connector\\c3p0-0.9.1.2.jar DB-connector\\mysql-connector-java-5.1.40-bin.jar DB-connector\\spring-jdbc-3.2.9.RELEASE.jar //AOP springAOP\\aopalliance.jar springAOP\\aspectjrt.jar springAOP\\aspectjweaver.jar springAOP\\spring-aop-3.2.9.RELEASE.jar //spring_ORM spring-ORM\\spring-orm-3.2.9.RELEASE.jar spring-ORM\\spring-tx-3.2.9.RELEASE.jar
2 创建数据库表
CREATE TABLE employee( id INT PRIMARY KEY AUTO_INCREMENT, ename VARCHAR(50) NOT NULL, depId INT, FOREIGN KEY(depId) REFERENCES department(id)); CREATE TABLE department( id INT PRIMARY KEY AUTO_INCREMENT, dname VARCHAR(50) NOT NULL);
3 写实体类
//Department public class Department { private int id; private String dname; private Set<Employee> dEmployees = new HashSet<Employee>(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public Set<Employee> getdEmployees() { return dEmployees; } public void setdEmployees(Set<Employee> dEmployees) { this.dEmployees = dEmployees; } } // Employee public class Employee { private int id; private String ename; private Department department = new Department(); public int getId() { return id; } public void setId(int id) { this.id = id; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { return "Employee [id=" + id + ", ename=" + ename + "]"; } }
注意:在实体类中有属性是其他类,要进行初始化动作。否则可能在以后操作数据时有问题。
4 Dao/Service/Action
// EmployeeDao public class EmployeeDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void saveEmployee(Employee emp){ sessionFactory.getCurrentSession().save(emp); } public Employee getEmployee(Employee emp){ Employee result = (Employee) sessionFactory.getCurrentSession().get(Employee.class, emp.getId()); return result; } public boolean isExistEmployee(Employee emp){ Object result = sessionFactory.getCurrentSession().get(Employee.class, emp.getId()); return result!=null; } public List<Employee> getAllEmployee(){ Query q = sessionFactory.getCurrentSession().createQuery("from Employee"); List<Employee>list = q.list(); return list; } } //EmployeeService public class EmployeeService { private EmployeeDao employeeDao; public void setEmployeeDao(EmployeeDao employeeDao) { this.employeeDao = employeeDao; } public void saveEmployee(Employee emp){ employeeDao.saveEmployee(emp); } public Employee getEmployee(Employee emp){ Employee result = null; if(employeeDao.isExistEmployee(emp)){ result = employeeDao.getEmployee(emp); } return result; } public List<Employee> getAllEmployee(){ return employeeDao.getAllEmployee(); } } //EmployeeAction public class EmployeeAction extends ActionSupport implements SessionAware,ApplicationAware,RequestAware{ private EmployeeService employeeService; private Map<String, Object> request; private Map<String, Object> session; private Map<String, Object> application; public void setEmployeeService(EmployeeService employeeService) { this.employeeService = employeeService; } public String getAllEmployees(){ List<Employee> allEmployees = employeeService.getAllEmployee(); // ActionContext.getContext().getContextMap().put("allEmployees", allEmployees); // ServletActionContext.getRequest().setAttribute("allEmployees", allEmployees); request.put("allEmployees", allEmployees); return SUCCESS; } @Override public void setRequest(Map<String, Object> arg0) { request = arg0; } @Override public void setApplication(Map<String, Object> arg0) { application = arg0; } @Override public void setSession(Map<String, Object> arg0) { session = arg0; } }
注意:
1)在这些类中如果有私有对象,要设置对应的set方法。因为所有对象的创建都交给了spring,需要有set方法与之对应。
2)在Action方法保存对象到域中有3中方法。具体可以参考之前博文struts2开发流程及配置,域对象对数据存储的3种方式。比较方便的是继承SessionAware,ApplicationAware,RequestAware接口
5 对spring和hibernate进行配置,将所有和数据库相关的配置都在spring配置中配置,配置文件bean.xml;以后项目如果比较大可以将bean-dao.xml,bean-service.xml,bean-action.xml,bean-base.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:p="http://www.springframework.org/schema/p" 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-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 1 dataSource config combopooleddatasource --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///day26?useSSl=true"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> <property name="initialPoolSize" value="2"></property> <property name="maxPoolSize" value="20"></property> <property name="acquireIncrement" value="2"></property> <property name="maxStatements" value="20"></property> </bean> <!-- 2 sessionFactory config --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 2.1 dataSource property --> <property name="dataSource" ref="dataSource"></property> <!-- 2.2 DB other property, dialect/showsql/ --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <!-- <prop key="hibernate.hbm2ddl.auto">create</prop> --> </props> </property> <!-- 2.3 mapping file list --> <property name="mappingLocations"> <list> <value>classpath:com/huitong/entity/*.hbm.xml</value> </list> </property> </bean> <!-- 3 dao/service/action bean --> <bean id="employeeDao" class="com.huitong.dao.EmployeeDao"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="employeeService" class="com.huitong.service.EmployeeService"> <property name="employeeDao" ref="employeeDao"></property> </bean> <bean id="employeeAction" class="com.huitong.action.EmployeeAction" scope="prototype"> <property name="employeeService" ref="employeeService"></property> </bean> <!-- 4 transaction config --> <!-- 4.1 transaction manager bean config --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 4.2 transaction advice --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true"/> <tx:method name="query*" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 4.3 AOP config --> <aop:config> <aop:pointcut expression="execution(* com.huitong.service.EmployeeService.*(..))" id="emppt"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="emppt"/> </aop:config> </beans>
6 struts配置,struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="Employeepkg" extends="struts-default" > <action name="employee_*" class="employeeAction" method="{1}"> <result name="success" type="dispatcher">/employeeList.jsp</result> </action> </package> </struts>
7 web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SSH1</display-name> <!-- 3 opensessioninview config, for lazyInitialization exception --> <filter> <filter-name>opensessionInview</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>opensessionInview</filter-name> <url-pattern>*.action</url-pattern> </filter-mapping> <!-- 1 struts config --> <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> <!-- 2 spring config --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/classes/bean*.xml</param-value>
<!--另一种方案<param-value>classpath:bean*.xml</param-value> --> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<welcome-file-list> <welcome-file>/index.jsp</welcome-file> </welcome-file-list> </web-app>
注意:在spring中配置事务,由于使用了懒加载。在jsp页面访问关联数据不能访问。事务配置在了service方法中,在action方法中无法获取相关联的数据。解决办法有四种,
1)在action方法中将要用到的数据先获取一遍
2)关闭懒加载,不过这种方法对于数据关系复杂的情况不太好,它会加载所有相关数据而不是用到什么取什么。
3)使用openSessionInViewFilter,注意配置的时候filter mapping要在struts的filter mapping之前。否则不起效果。
4)在service层强行初始化代理对象
8 前台页面employeeList.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/struts-tags" prefix="s"%> <%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <% 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>所有员工信息</title> </head> <body> <div> <table cellpadding="5" cellspacing="0" align="center" border="1"> <tr> <th>员工名</th> <th>部门</th> </tr> <c:forEach items="${requestScope.allEmployees }" var="emp" varStatus="empStatus"> <tr> <td>${emp.ename }</td> <td>${emp.department.dname }</td> </tr> </c:forEach> </table> </div> </body> </html>
9 简单测试
public void fun1(){ ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); EmployeeService empService = (EmployeeService) ac.getBean("employeeService"); System.out.println(empService); //spring ok? Employee emp1 = new Employee(); emp1.setEname("good"); Employee emp2 = new Employee(); emp2.setEname("nice"); Department department = new Department(); department.setDname("软件开发部"); emp1.setDepartment(department); emp2.setDepartment(department); empService.saveEmployee(emp1); empService.saveEmployee(emp2);//hibernate ok? }
项目在github上的地址https://github.com/crazyCodeLove/SSHpro1.git
struts输入表单中的隐藏域可以使用<s:hidden>
<s:hidden name="id"></s:hidden>
以上是关于ssh整合,从hibernate那个版本开始需要open session in view 才能开启事务?的主要内容,如果未能解决你的问题,请参考以下文章
SSH框架系列之 Spring 整合 Hibernate 框架