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
View Code

 

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 + "]";
    }
}
View Code

注意:在实体类中有属性是其他类,要进行初始化动作。否则可能在以后操作数据时有问题。

 

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

}
View Code

注意:

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>
View Code

 

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框架整合详解一

SSH整合

SSH整合简单例子

SSH框架系列之 Spring 整合 Hibernate 框架

spring+struts2+hibernate整合(ssh)

SSH整合做CRUD(大神老师整理)