• 第21届上海国际电影节启幕 设“一带一路电影周” 2019-04-11
  • 广西壮族自治区东兰县“七民一站一阵地工作法”维护群众权益 2019-04-08
  • 苗山脱贫影像志——父母在 不远行 2019-04-08
  • 竹编:缝隙里的乡愁文章中国国家地理网 2019-03-31
  • “几乎是时时在流血、天天有牺牲”,他们的故事你知道吗? 2019-03-31
  • 当前位置:浙江十一选五开奖直播 >  域名 >  正文 > 裸露胸部就是下流吗?

      交易 任务 SEO服务 站长团购 联盟

    舞衣眼中露出了迷醉的神色,她叹了一口气,“如此凄美的乐府,我还是第一次听到?!?/p>

    老师不让一年级小孩出去玩和说话,只让写作业,对么?

    其他人也觉得有趣,纷纷参与起来。少则几万,多则几千万,筹码已经堆了一大堆,不过这些钱对于这些富豪来说,也只是九牛一毛而已。
    “哎呀呀!”癫和尚拍着手说道:“和尚我说刚才怎么那么大的动静的,原来是纪小子将你治好了呀?!?/p>

    李隆基笑了,李庆安的表态让他心中轻轻松了一口气,只要李庆安接收这一点,其他什么都好商量,他点点头笑道:“这次陇右之战有功有罪,有功者,朕会给予重赏,有罪者,朕也会给予重罚,朕一定会赏罚分明,虽然在此战中,给你定的拦截功劳为第三,但你还有其他的功劳,比如火药,就凭这一点,朕就可以在战役以外对你进行额外的封赏,你明白吗?”

    SSH框架完全整合


    大三学期渐末,事情也挺多的,上周就开始着手整合SSH框架,到现在才真正的完成,过程中碰到了许多小问题(小问题大折腾,哭脸.jpg)。本着善始善终的原则,最终把它给完成了。

    本篇文章就在:
    win7 64位,eclipse最新版(2017.9),Spring4.3.13,Hibernate5.0.1,Struts2.3.34 环境下,整合SSH。在下一篇文章,我们也来使用Maven来整合一下(毕竟学了就要用嘛,哈哈)。

    首先先介绍一下jar包:
    这里写图片描述

    这里写图片描述

    以上是我使用完整的jar包清单,我们分别导入了三个框架所需要的jar包,在导jar包的时候需要注意以下几点:

    • jar包冲突:struts2的javassist和Hibernate的javassist有冲突,我们选择最新的版本的(根据你的自身情况选择)。
    • log4j,log4j-api,log4jcore,slf4j-api,slf4j-log4j12的的冲突,我们依旧看情况选择最新版本。
    • c3p0jar包,我们选择最新的(框架之间有重复的记得删除重复)。
    • Spring整合struts2需要导入Spring-web和struts2-spring-plugin jar包,不要丢掉。
    • 数据库jar驱动jar包,根据自身使用的数据库进行选择
    • 因为我这里使用Spring对事务的管理,所以还要导入事务的jar包,spring -jdbc的jar包,spring-orm,Aspectj的jar包。

    以上都是我们需要特别注意的,否则整合的过程中会给你带来不小的麻烦

    jar包就介绍差不多了,那我们就来开始吧:
    首先看一下我的目录结构:
    这里写图片描述

    项目大体可以分为三层,视图层,service层,DAO层,因为我们这里没有什么业务,单纯的是调用DAO,所以可能service层和DAO层之间的区别不是很明显。

    其实三个框架的整合,就是将Hibernate的session创建交给Spring,将Struts2的Action交给Spring。

    (一)在Hibernate中,我们自己通过以下的一系列操作获取session:

             //加载配置文件
            Configuration config = new Configuration().configure();
            //根据配置文件创建会话工厂
            SessionFactory factory = config.buildSessionFactory();
            //根据会话工厂创建会话
            Session session = factory.getCurrentSession();
            //创建一个事物对象
            Transaction tx = session.beginTransaction();
            //new 一个学生对象
            Student student = new Student("小三",19,99);
            //将对象持久化到数据表中
            session.save(student);
            //提交事务
            tx.commit();
            //关闭会话
            session.close();
            //关闭工厂
            factory.close();

    同样为了解耦,在项目中,我们不再自己手动的来获取session了,而是通过Spring来帮我们创建,并且service层中需要DAO,DAO需要session,也是Spring进行注入。

    (二)在Struts2中,我们通过自己在Struts2的主配置文件中指定对应请求的Action的全限定类名,Struts2和Spring整合则是将Action的创建交给了Spring,由Spring来管理Action对象。

    接下来我们就这两个方面分别整合Spring和Hibernate,Spring和Struts2,最后在Struts2 Action的execute方法中调用service,对业务进行操作。

    下面为了代码的可读性,博主不会将代码分块分析,很重要的将会指出,大多数的过程说明将在注释中给出:


    整合Spring和Hibernate:

    先给出我们的基本代码:

    //DAO接口:
    public interface StudentDao {
        void insert(Student student);
        void delete(Student student);
        void update(Student student);
        List<Student> selectAllStudents();
        boolean selectStudentByIdAndName(String name,int age);
    }
    //DAO的实现类,里面注入了SessionFactory对象,利用这个我们可以获取session
    
    public class StudentDaoImpl implements StudentDao{
        //这里的sessionFactory由Spring进行注入
        private SessionFactory sessionFactory;
        //所以这里需要setter方法,这里的getter方法顺带添上,如果以后需要获取sessionFactory的话可以调用
        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }
        //依赖注入,需要setter方法
        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }
    
        @Override
        public void insert(Student student) {
            sessionFactory.getCurrentSession().save(student);
        }
    
        @Override
        public void delete(Student student) {
            sessionFactory.getCurrentSession().delete(student);
        }
    
        @Override
        public void update(Student student) {
            sessionFactory.getCurrentSession().update(student);
        }
    
    
        @Override
        public List<Student> selectAllStudents() {
            String hql = "from Student";
            return sessionFactory.getCurrentSession().createQuery(hql).list();
        }
    
        //通过name和age来判别学生是否存在
        @Override
        public boolean selectStudentByIdAndName(String name, int age) {
            String hql = "from Student where name=? and age=?";
            boolean flag = false;
            if(sessionFactory.getCurrentSession().createQuery(hql).setString(0, name).setInteger(1, age).uniqueResult()!=null) {
                flag = true;
            }
            return flag;
        }
    }

    上面的DAO,我们获取session不再使用原始的方法了,而是使用Spring注入的方式为我们程序获取session,具体的SessionFactory配置,将在后面的Spring配置文件给出。


    接下来我们看Service:

    //service接口
    public interface StudentService {
        void add(Student student);
        void remove(Student student);
        void modify(Student student);
        List<Student> findAllStudents();
        boolean findByNameAndAge(String name,int age);
    }

    //service实现类
    public class StudentServiceImpl implements StudentService {
        //这里的Dao对象是由Spring注入,下面要有setter方法
        private StudentDao studentdao; 
        public StudentDao getStudentdao() {
            return studentdao;
        }
        public void setStudentdao(StudentDao studentdao) {
            this.studentdao = studentdao;
        }
        @Override
        public void add(Student student) {
            studentdao.insert(student);
        }
    
        @Override
        public void remove(Student student) {
            studentdao.delete(student);
            
        }
    
        @Override
        public void modify(Student student) {
            studentdao.update(student);
            
        }
    
        @Override
        public List<Student> findAllStudents() {
            return studentdao.selectAllStudents();
        }
        @Override
        public boolean findByNameAndAge(String name, int age) {
            return studentdao.selectStudentByIdAndName(name, age);
        }
        
    }

    接着便是我们Spring的配置文件(下面的配置文件是完整的配置文件,即整合ssh的完整配置文件,其实也就是在整合Hibernate的基础上注册了Action类的bean):

    <?xml version="1.0" encoding="utf-8"?>
        <beans xmlns="//www.springframework.org/schema/beans"
        xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
        xmlns:context="//www.springframework.org/schema/context"
        xmlns:aop="//www.springframework.org/schema/aop"
        xmlns:tx="//www.springframework.org/schema/tx"
        xsi:schemaLocation="//www.springframework.org/schema/beans
        //www.springframework.org/schema/beans/spring-beans.xsd
        //www.springframework.org/schema/context
        //www.springframework.org/schema/context/spring-context.xsd
        //www.springframework.org/schema/aop
        //www.springframework.org/schema/aop/spring-aop.xsd
        //www.springframework.org/schema/tx
        //www.springframework.org/schema/tx/spring-tx.xsd">
    
        <!-- 注册c3p0数据源 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.jdbc.Driver"/>
            <!--处理中文乱码问题-->
            <property name="jdbcUrl" value="jdbc:mysql:///test?useUnicode=true&amp;characterEncoding=utf8"/>
            <property name="user" value="root"/>
            <property name="password" value="123"/>
            <!-- ?useUnicode=true&amp;characterEncoding=utf8 -->
        </bean>
        
        <!-- 注册sessionFactory -->
        <bean id="MysessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!--不要缺少classpath,否则在整合Struts2时候会找不到映射文件-->
            <property name="mappingDirectoryLocations" value="classpath:com/testSpring/Entity"/>
            
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
                </props>
            </property>
        </bean>
        
        <!-- 注册studentDao -->
        <bean id="StudentDao" class="com.testSpring.Dao.StudentDaoImpl">
            <property name="sessionFactory" ref="MysessionFactory"></property>
        </bean>
        
        <!-- 注册studentService -->
        <bean id="studentservice" class="com.testSpring.Service.StudentServiceImpl">
            <property name="studentdao" ref="StudentDao"/>
        </bean>
        
        <!-- 将Action交由Spring来管理  ref里面的studentservice引用的是上面的bean,这个是多例的,因为每个请求对应一个Action,不能多个用户共用一个Action-->
        <bean id="RegisterAction" class="com.testSpring.Action.RegisterAction" scope="prototype">
            <property name="studentservice" ref="studentservice"/>
        </bean>
        
        <!-- 注册事务管理器 -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <property name="sessionFactory" ref="MysessionFactory"/>
        </bean>
        
        <!-- 注册事务通知 -->
        <tx:advice id="myAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add" isolation="DEFAULT" propagation="REQUIRED"/>
                <tx:method name="remove" isolation="DEFAULT" propagation="REQUIRED" />
                <tx:method name="modify" isolation="DEFAULT" propagation="REQUIRED" />
                <tx:method name="findAllStudents" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
                <tx:method name="findByNameAndAge" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/>
            </tx:attributes>
        </tx:advice>
        
        <!-- aop配置切入点 -->
        <aop:config>
            <aop:pointcut expression="execution(* *..Service.*.*(..))" id="myPointCut"/>
            <aop:advisor advice-ref="myAdvice" pointcut-ref="myPointCut"/>
        </aop:config>
    </beans>

    整合Hibernate,
    我们需要注册SessionFactory,
    class为org.springframework.orm.hibernate5.LocalSessionFactoryBean,位于我们Spring orm包下,对于不同版本的Hibernate,我们应该选用不同的整合class。

    上面的Spring主配置文件中用<property name="hibernateProperties">属性来替代了我们导入Hibernate的主配置文件,当然我们也可以直接导入Hibernate的主配置文件,不过为了简洁,我们这样比较方便。

    关于配置文件后面对事务的管理,我们这里就不多说了,我的前几篇文章都有详细的介绍,有兴趣的同学可以去看看:
    //blog.csdn.net/qq_39266910/article/details/78826171


    如果做到上面的这些,我们便可以进行测试了:

    //测试类
    public class Test01 {
        private StudentService service;
        
        @Before
        public void before() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            service = (StudentService)ac.getBean("studentservice");
        }
    
        @Test
        public void test01() {
            service.add(new Student("中文",18));
            System.out.println("Success");
        }
        
        @Test
        public void test02() {
            Student student = new Student();
            student.setId(1);
            service.remove(student);
        }
        
        @Test
        public void test03() {
            Student student = new Student("张三",25);
            student.setId(10);
            service.modify(student);
        }
        
        @Test
        public void test06() {
            System.out.println(service.findAllStudents());
        }
        
        @Test
        public void test07() {
            System.out.println(service.findByNameAndAge("中", 18));
        }
    }

    以上就是Spring整合Hibernate的全过程,接下来我们来整合Struts2:


    Spring整合Struts2

    首先是Struts2的主配置文件:

    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "//struts.apache.org/dtds/struts-2.3.dtd">
        
    <struts>
         <constant name="struts.enable.DynamicMethodInvocation" value="false" />
         <constant name="struts.devMode" value="true" />
    
         <package name="default" namespace="/" extends="struts-default" >
         <!--下面的全限定类名可以改为RegisterAction,当我们在Spring中注册当前Action类的bean-->
                <action name="register" class="com.testSpring.Action.RegisterAction">
                <result name="success">/welcome.jsp</result>
                <result name="error">/error.jsp</result>
            </action>
        </package>
    </struts>

    接着是对应的Action:

    public class RegisterAction extends ActionSupport{
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private String name;
        private int age;
        //Spring会为我们自动注入service,但是这个属性名要和Spring主配置文件里面注册的studentservice的id保持一致。
        //或者将Action交由Spring管理,在Spring配置Action的bean,为bean注入service,如果这样,我们在struts2主配置文件的class就不必写成Action的全限定类名,而是Spring中注册的id。
        private StudentService studentservice;
        public RegisterAction() {
            super();
        }
        
        public RegisterAction(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        
        //  注入Service,我们需要保留set方法
        public void setStudentservice(StudentService studentservice) {
            this.studentservice = studentservice;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String execute() {
            System.out.println(studentservice);
            System.out.println(name);
            System.out.println(age);
            studentservice.add(new Student(name,age));
            return SUCCESS;
        }
    }

    以上是模拟完成一个注册功能,view层发送一个请求,包含姓名和年龄,后台负责接收,并调用service层进行处理,service层调用DAO,DAO调用SessionFactory获取session,最终达到对数据库的操作。

    如果仅仅这样你是不是忘了些什么?
    ①我们需要在web.xml中添加Struts2的核心过滤器。
    ②设置一个监听器,监听当web容器创建的时候,即创建我们的Spring容器,这样我们不再需要自己加载Spring的主配置文件。
    ③设置web容器全局参数,自定义Spring主配置文件的位置和命名

    具体的看web.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="//java.sun.com/xml/ns/javaee"
        xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="//java.sun.com/xml/ns/javaee
        //java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
        
      <!--  自定义Spring主配置文件的位置 -->
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
      </context-param>
      
      <!-- 使用ContextLoaderListener初始化Spring容器 -->
      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
        
      <!-- 定义Struts 2的FilterDispathcer的Filter -->
      <filter>
          <filter-name>struts2</filter-name>
          <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      </filter>
      <!-- FilterDispatcher用来初始化Struts 2并且处理所有的WEB请求。 -->
      <filter-mapping>
          <filter-name>struts2</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
    </web-app>

    我们一并给出jsp页面(success和error页面就不写了,一个形式):

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "//www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>register</title>
    </head>
    <body>
        <form action="register" method="post">
            姓名<input type="text" name="name"><br>
            年龄<input type="text" name="age"><br>
            <input type="submit" value="注册">    
        </form>
    </body>
    </html>

    接下来我们进行测试:
    这里写图片描述

    点击后,跳转到:
    这里写图片描述

    最后看看数据库:

    这里写图片描述


    以上的ssh整合大体上是没有什么问题的,但是碰上延时加载的话会出现一些意想不到的事情,在讲Hibernate的session的时候,我们说过session有两种获取的方式,一个是getCurrentSession,另一个是openSession,它们两个获取的session的区别是,getSession获得的session必须要在事务中执行,也就说没有事务是不能获取session的,当我们使用session.load进行查询的时候,这就是一个延时加载,执行加载方法的时候会产生一个代理,这个代理是一个空代理,只有当我们真正需要这个代理的详细数据的时候,才会真正的进行查询,但是当它真正的查询的时候,已经没有了事务(因为我们这里的事务是通过Spring整合AspectJ,通过AOP的方式实现添加事务的),所以这个时候也就没有了session,所以当再执行详情查询的时候就会报错(no session)。

    所以我们需要在web.xml中添加一个过滤器,来获取session,这个过滤器的名字叫做OpenSessionInViewFilter,添上这个过滤器后,当我们进行延时加载的话,就不会再出现no session的情况了!
    在OpenSessionInViewFilter的源码中,获取session是利用的SessionFactory,也就是我们自己在Spring的注册的SessionFactory,且在里面,这个类有一个默认的SessionFactory名字就叫做sessionFactory:

    这里写图片描述

    注意:添加这个过滤器,一定要在Struts2的核心过滤器之前!
    具体原因是:Struts2的核心过滤器中,当有Action请求的时候,会执行executeAction方法,即执行Action,不会有chain.doFilter(执行下一个过滤器),有源码有真相:
    这里的mapping就是对应的action请求。
    这里写图片描述

    下面是openSessionInViewFilter的具体配置方法,初始化参数是为了自定义我们的sessionFactory的bean id,因为openSessionInViewFilter里面有setter方法,可以为之前设置好的默认值进行修改。

    这里写图片描述


    总结:当代码都写出来了,觉得很简单,但是这过程中一直小bug不断(当然大多数都是由自己的粗心造成的),其实三个框架之间的真核无非就是将所有关于类的创建管理交由Spring,由Spring来为需要的注入所需要的bean,不再需要手动的创建一个个的类,使得各个层级之间耦合度降低,即使一层代码出现了问题不需要修改另一层的代码,便于我们项目的维护和更新,也便于出现问题能够即使定位出错的位置。


    以上是自己的心得体会,代码均由博主亲自验证,可以运行,文章方便博主以后查阅,也供大家参考,如有错误不吝赐教!

    当前文章://www.wmdzr.com/seoguwen/

    发布时间:2019-04-07 02:06:23

    蜗牛的脑容量 最初的梦想 孩子如何面对 怀孕日记——准妈妈的选择题 阴魂不散的前女友 别和自己过不去 圣诞节预热:诺心lecake星愿蛋糕真好吃! 因为爱情最经不起考验

    建国以来最大规模的阅兵-2015阅兵 如何在爱情、婚姻生活中跨越“不踏实感” 为何你不懂我 关于自行车的冷知识 情人节需要花钱 你真的适合创业吗?答案是“未必”! 15岁挣到500万 没有爸,妈又不喜欢,丈夫还发脾气骂人。我该怎么办? 突破“离婚”或“凑合过”的婚姻困惑 这样做吸引,才如家、才你家、才我家 当父母在做这十件事时,请让孩子看见 朴槿惠:我来,只为人要活得真诚和正直 一个国家和社会的品味其实是由女人决定的 智商仅次于爱因斯坦的天才男孩需要帮助! 脚语 独特的心理泄露 超常儿童的幼小衔接之路 孩子入园不适怎么办? 让中国女人憧憬的男朋友朋友圈应该是什么样子的? 为什么我们要称呼他为芈月呢?

    编辑:邓伯

      文章推荐

      分类排行榜

      专栏文章

      更多>

      服务推荐

      浙江十一选五开奖直播
      罗李华谈:属龙的人2016年运程 扫一扫关注最新创业资讯
    • 第21届上海国际电影节启幕 设“一带一路电影周” 2019-04-11
    • 广西壮族自治区东兰县“七民一站一阵地工作法”维护群众权益 2019-04-08
    • 苗山脱贫影像志——父母在 不远行 2019-04-08
    • 竹编:缝隙里的乡愁文章中国国家地理网 2019-03-31
    • “几乎是时时在流血、天天有牺牲”,他们的故事你知道吗? 2019-03-31