• 【Java EE 学习 53】【Spring学习第五天】【Spring整合Hibernate】【Spring整合Hibernate、Struts2】【问题:整合hibernate之后事务不能回滚】


    一、Spring整合Hibernate

      1.如果一个DAO 类继承了HibernateDaoSupport,只需要在spring配置文件中注入SessionFactory就可以了;如果一个DAO类没有继承HibernateDaoSupport,需要有一个HibernateTemplate的属性,并且在配置文件中进行注入。注意,之前使用的是JdbcDaoSupport和JdbcTemplate,传递的是DataSource,现在使用的是HibernateDaoSupport和HibernateTemplate,传递的是SessionFactory。

      2.整合Spring整合Hibernate示例。

        (1)hibernate.cfg.xml配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
     5 <hibernate-configuration>
     6 <session-factory>
     7     <property name="connection.driver_class">
     8         com.mysql.jdbc.Driver
     9     </property>
    10     <property name="connection.username">root</property>
    11     <property name="connection.password">5a6f38</property>
    12     <property name="connection.url">
    13         jdbc:mysql://localhost:3306/test
    14     </property>
    15     <property name="show_sql">true</property>
    16     <property name="hbm2ddl.auto">update</property>
    17     <property name="dialect">
    18         org.hibernate.dialect.MySQLDialect
    19     </property>
    20     <property name="javax.persistence.validation.mode">none</property>
    21     <mapping resource="com/kdyzm/spring/hibernate/xml/Course.hbm.xml" />
    22 </session-factory>
    23 </hibernate-configuration>
    hibernate.cfg.xml

        (2)几个类

     1 package com.kdyzm.spring.hibernate.xml;
     2 
     3 import java.io.Serializable;
     4 
     5 /*
     6  * 课程类
     7  */
     8 public class Course implements Serializable{
     9     private static final long serialVersionUID = 3765276226357461359L;
    10     private Long cid;
    11     private String cname;
    12     
    13     public Course() {
    14     }
    15     @Override
    16     public String toString() {
    17         return "Course [cid=" + cid + ", cname=" + cname + "]";
    18     }
    19     public Long getCid() {
    20         return cid;
    21     }
    22     public void setCid(Long cid) {
    23         this.cid = cid;
    24     }
    25     public String getCname() {
    26         return cname;
    27     }
    28     public void setCname(String cname) {
    29         this.cname = cname;
    30     }
    31 }
    com.kdyzm.spring.hibernate.xml.Course
    1 package com.kdyzm.spring.hibernate.xml;
    2 
    3 public interface CourseDao {
    4     public Course getCourse(Long cid);
    5     public Course updateCourse(Course course);
    6     public Course deleteCourse(Course course);
    7     public Course addCourse(Course course);
    8 }
    com.kdyzm.spring.hibernate.xml.CourseDao

        一个非常重要的类:com.kdyzm.spring.hibernate.xml.CourseDaoImpl

     1 package com.kdyzm.spring.hibernate.xml;
     2 
     3 import org.springframework.orm.hibernate3.HibernateTemplate;
     4 
     5 public class CourseDaoImpl implements CourseDao{
     6     //这里使用HibernateTemplate,而不是使用JdbcTemplate
     7     private HibernateTemplate hibernateTemplate;
     8     public HibernateTemplate getHibernateTemplate() {
     9         return hibernateTemplate;
    10     }
    11 
    12     public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
    13         this.hibernateTemplate = hibernateTemplate;
    14     }
    15 
    16     @Override
    17     public Course getCourse(Long cid) {
    18         return (Course) this.getHibernateTemplate().get(Course.class, cid);
    19     }
    20 
    21     @Override
    22     public Course updateCourse(Course course) {
    23         this.getHibernateTemplate().update(course);
    24         return course;
    25     }
    26 
    27     @Override
    28     public Course deleteCourse(Course course) {
    29         this.getHibernateTemplate().delete(course);
    30         return course;
    31     }
    32 
    33     @Override
    34     public Course addCourse(Course course) {
    35         this.getHibernateTemplate().saveOrUpdate(course);
    36         return course;
    37     }
    38     
    39 }

        这里使用HibernateTemplate作为成员变量,也可以继承HibernateDaoSupport类,效果是相同的。

    1 package com.kdyzm.spring.hibernate.xml;
    2 
    3 public interface CourseService {
    4     public Course getCourse(Long cid);
    5     public Course updateCourse(Course course);
    6     public Course deleteCourse(Course course);
    7     public Course addCourse(Course course);
    8 }
    com.kdyzm.spring.hibernate.CourseService
     1 package com.kdyzm.spring.hibernate.xml;
     2 
     3 public class CourseServiceImpl implements CourseService{
     4     private CourseDao courseDao;
     5     
     6     public CourseDao getCourseDao() {
     7         return courseDao;
     8     }
     9 
    10     public void setCourseDao(CourseDao courseDao) {
    11         this.courseDao = courseDao;
    12     }
    13 
    14     @Override
    15     public Course getCourse(Long cid) {
    16         return courseDao.getCourse(cid);
    17     }
    18 
    19     @Override
    20     public Course updateCourse(Course course) {
    21         return courseDao.updateCourse(course);
    22     }
    23 
    24     @Override
    25     public Course deleteCourse(Course course) {
    26         return courseDao.deleteCourse(course);
    27     }
    28 
    29     @Override
    30     public Course addCourse(Course course) {
    31         return courseDao.addCourse(course);
    32     }
    33 
    34 }
    com.kdyzm.spring.hibernate.xml.CourseServiceImpl

        最后:测试代码

     1 ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/hibernate/xml/applicationContext.xml");
     2 CourseService courseService=(CourseService) context.getBean("courseService");
     3 Course course = new Course();
     4 //        course.setCid(11L);
     5 course.setCname("赵日天");
     6 courseService.addCourse(course);
     7 course =new Course();
     8 course.setCname("王大锤");
     9         //通过/0的异常测试事务回滚!
    10 //        int a=1/0;
    11 courseService.addCourse(course);

        运行结果:

        

        (3)com/kdyzm/spring/hibernate/xml/applicationContext.xml配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:aop="http://www.springframework.org/schema/aop"
     6     xmlns:tx="http://www.springframework.org/schema/tx"
     7     
     8     xsi:schemaLocation="
     9            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    10            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    11            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    12            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    13            ">
    14     <!-- 将hibernate.cfg.xml配置文件导入进来 -->
    15     <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    16         <property name="configLocation">
    17             <value>classpath:hibernate.cfg.xml</value>
    18         </property>
    19     </bean>
    20     
    21     <!-- 程序员做的事情 -->
    22     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
    23         <property name="sessionFactory" ref="sessionFactory"></property>
    24     </bean>
    25     <bean id="courseDao" class="com.kdyzm.spring.hibernate.xml.CourseDaoImpl">
    26         <property name="hibernateTemplate" ref="hibernateTemplate"></property>
    27     </bean>
    28     
    29     <bean id="courseService" class="com.kdyzm.spring.hibernate.xml.CourseServiceImpl">
    30         <property name="courseDao">
    31             <ref bean="courseDao"/>
    32         </property>
    33     </bean>
    34     
    35     <!-- Spring容器做的事情 -->
    36     <!-- 定义事务管理器 -->
    37     <bean id="hibernateTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    38         <property name="sessionFactory" ref="sessionFactory"></property>
    39     </bean>
    40     <!-- 哪些通知需要开启事务模板 -->
    41     <tx:advice id="advice" transaction-manager="hibernateTransactionManager">
    42         <tx:attributes>
    43             <tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
    44         </tx:attributes>
    45     </tx:advice>
    46     <!-- 配置切面表达式和通知 -->
    47     <aop:config>
    48         <aop:pointcut expression="execution(* com.kdyzm.spring.hibernate.xml.*ServiceImpl.*(..))" id="perform"/>
    49         <aop:advisor advice-ref="advice" pointcut-ref="perform"/>
    50     </aop:config>
    51 </beans>

      3.总结和分析

        (1)和使用JDBC的流程基本上是相同的,需要在配置文件中注入SessionFactory对象,注入HibernateTemplate对象。

        (2)以上的程序事务回滚没有实现!!!!原因不明

    二、Spring整合Hibernate,使用注解的形式。

      1.在配置文件中使用spring的自动扫描机制。

    <context:component-scan base-package="com.kdyzm.spring.hibernate.xml"></context:component-scan>

      2.在配置文件中引入注解解析器(需要指定事务管理器)

    <tx:annotation-driven transaction-manager="hibernateTransactionManager"/>

      3.在service层通过@Transaction进行注解。

     三、Struts2自定义结果集

      1.struts-default.xml文件中定义了一些结果集类型。

     1 <result-types>
     2             <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
     3             <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
     4             <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
     5             <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
     6             <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
     7             <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
     8             <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
     9             <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
    10             <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
    11             <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
    12             <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
    13         </result-types>
    struts-default.xml配置文件中对结果集类型的定义

      2.我们可以通过实现Result接口或者继承StrutsResultSupport类自己定义结果集类型

        * 如果我们不需要跳转页面(使用了Ajax),则实现Result接口

          * 如果我们需要在业务逻辑处理完毕之后进行页面的跳转(重定向或者转发),则继承StrutsResultSupport类。

      3.自定义结果集小案例

        (1)自定义结果集类型com.kdyzm.struts2.myresult.MyResult.java,这里继承了StrutsResultSupport类,这里的代码模仿了DispatcherResult类中的写法。

           自定义结果集类型中的核心写法已经重点标注。

     1 package com.kdyzm.struts2.myresult;
     2 
     3 import javax.servlet.RequestDispatcher;
     4 import javax.servlet.http.HttpServletRequest;
     5 import javax.servlet.http.HttpServletResponse;
     6 
     7 import org.apache.struts2.ServletActionContext;
     8 import org.apache.struts2.dispatcher.StrutsResultSupport;
     9 
    10 import com.opensymphony.xwork2.ActionInvocation;
    11 
    12 public class MyResult extends StrutsResultSupport{
    13     private static final long serialVersionUID = 8851051594485015779L;
    14 
    15     @Override
    16     protected void doExecute(String finalLocation, ActionInvocation invocation)
    17             throws Exception {
    18         System.out.println("执行了自定义的 结果集类型!");
    19         HttpServletRequest request=ServletActionContext.getRequest();
    20         HttpServletResponse response = ServletActionContext.getResponse();
    21         RequestDispatcher requestDispatcher = request.getRequestDispatcher(finalLocation);
    22         requestDispatcher.forward(request, response);
    23     }
    24 }

        (2)测试Action:com.kdyzm.struts2.myresult.MyResultAction.java

     1 package com.kdyzm.struts2.myresult;
     2 
     3 import com.opensymphony.xwork2.ActionSupport;
     4 
     5 public class MyResultAction extends ActionSupport {
     6     private static final long serialVersionUID = -6710770364035530645L;
     7 
     8     @Override
     9     public String execute() throws Exception {
    10         return super.execute();
    11     }
    12     
    13     public String add() throws Exception{
    14         return "myresult";
    15     }
    16 }

        (3)局部配置文件com.kdyzm.strus2.myresult.myResult_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>
        <package name="myResult" namespace="/myResultNamespace" extends="struts-default">
            <!-- 自定义结果集类型 -->
            <result-types>
                <result-type name="myResult" class="com.kdyzm.struts2.myresult.MyResult"></result-type>
            </result-types>
            <action method="add" name="myResultAction" class="com.kdyzm.struts2.myresult.MyResultAction">
                <result name="myresult" type="myResult">
                    <param name="location">
                        /main/index.jsp
                    </param>
                </result>
            </action>
        </package>
    </struts>

        (4)classpath:struts.xml

     1 <?xml version="1.0" encoding="utf-8" ?>
     2 <!DOCTYPE struts PUBLIC
     3     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
     4     "http://struts.apache.org/dtds/struts-2.3.dtd">
     5     <!-- namespace一定要加上/,否则一般会报错! -->
     6 <struts>
     7     <package name="kdyzm" extends="struts-default" namespace="/kdyzm_namespace">
     8         <action name="helloAction" class="com.kdyzm.struts2.test.HelloWorldAction" method="execute">
     9             <result name="kdyzm_result">
    10                 /main/index.jsp
    11             </result>
    12         </action>
    13     </package>
    14 <include file="com/kdyzm/struts2/myresult/myResult_struts.xml"></include></struts>
    struts.xml

        (5)测试Jsp

    <a href="${pageContext.servletContext.contextPath}/myResultNamespace/myResultAction.action">
                测试自定义结果集
    </a>

        (6)跳转到/main/index.jsp,显示出

          

     四、SSH整合

      1.整合的第一步:导入jar包,在/WEB-INF/lib文件夹下,按照功能划分为几个文件夹,分别存放不同类型的jar包。

        * common:存放公共包

        * db:存放数据库驱动包

        * hibernate:存放hiberante相关包

        * junit:存放单元测试相关包

        * spring:存放spring相关包

        * struts2:存放struts2相关包

        尽可能的将jar包关联上源代码,便于代码追踪和书写。

      2.创建三个项目资源文件夹和对应的包

        (1)src:存放源代码

          * dao

          * dao.impl

          * service:

          * service.impl

          * struts.action

          * domain

        (2) config:存放配置文件

          * hibernate

            * hibernate.cfg.xml

          * spring

            * applicationContext-db.xml

            * applicationContext-person.xml

            * applicationContext.xml

          * struts2

            struts-user.xml

          struts.xml

        (3)test:单元测试

      3.SSH整合的jar包、关键类文件和配置文件

        (1)Spring和Hibernate的整合过程见前面的笔记。

        (2)关键的就是Spring和Struts2的整合

        (3)Spring和Struts2整合需要一个关键的jar包:struts-spring-plugin-x.x.x.jar,该jar包可以在struts2项目中的lib文件夹中找到。

        (4)在struts-spring-plugin.x.x.x.jar包中有一个非常重要的配置文件:struts-plugin.xml配置文件,该配置文件中的配置会覆盖掉struts-default.xml中的配置。

        (5)需要在struts.xml配置文件中进行如下配置:

    <constant name="struts.objectFactory" value="spring"></constant>

          进行这样的配置之前必须导入struts-spring-plugin.x.x.x.jar包。

          能够这样配置的依据是该jar包中的struts-plugin.xml配置文件中的配置:

    <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />

        (6)怎样将Spring容器的初始化和Web服务器绑定在一起,使得服务器启动之后Spring容器就已经初始化成功。

          解决方案就是在web.xml配置文件中添加一项监听器的配置。

    1 <listener>
    2         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    3     </listener>
    4     <context-param>
    5         <param-name>contextConfigLocation</param-name>
    6         <param-value>classpath:spring/applicationContext.xml</param-value>
    7     </context-param>

          其中param-name标签中的内容contextConfigLocation是固定字符串,不能更改。contextConfigLocation字符串的出处:

          

         (7)applicationContext.xml配置文件默认位置为:/WEB-INF/applicationContext.xml,通过XmlWebApplicationContext.xml配置文件就可以看出来。

          

           所以,如果applicationContext.xml在/WEB-INF目录下的话,就不需要再配置

    <context-param>
             <param-name>contextConfigLocation</param-name>
              <param-value>classpath:spring/applicationContext.xml</param-value>
          </context-param>

          了。

    五、整合模板代码

      https://github.com/kdyzm/day53_ssh_merge

      

  • 相关阅读:
    B
    A
    P1057 传球游戏
    P1702 突击考试
    P1394 山上的国度
    P2117 小Z的矩阵
    P1510 精卫填海
    P1294 高手去散步
    P1071 潜伏者
    保留
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4855034.html
Copyright © 2020-2023  润新知