• SSH(struts2,spring4,hibernate5)详解


    使用ssh框架的目的:

      将典型的J2EE结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。

     struts2的核心与工作原理

        在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处?

    设计目标

        Struts设计的第一目标就是使MVC模式应用于web程序设计。

    mvc的好处:

     利于批量生产、规模生产、相互协作、推广普及。

    mvc的坏处:

     不利个案创作、独立创作、难艺术化、难个性化。

    技术优势

        Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The JavaServlet API揭示了Java Servlet只是Java API的一个很小子集,这样我们可以在业务逻辑部分使用功能强大的Java语言进行程序设计。

        二是提供了对MVC的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:拦截器、OGNL表达式语言、堆栈。

     因为struts2有这样目标,并且有这样的优势,所以,这是我们学习struts2的理由,下面,我们在深入剖析一下struts的工作原理。

    工作原理

    Suruts2的工作原理可以用下面这张图来描述:

      

     一个请求在Struts2框架中的处理大概分为以下几个步骤 :

      1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求

      2、这个请求经过一系列的过滤器(Filter)

     这个Filter 启动须要在在wed.xml配置文件里配置,配置详情如下:(注:前提要导入struts2的相关jar包

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

     配置了Filter后,就会读struts.xml配置文件 ,根据struts.xml配置文件找到对应的Action 并实例化该Action 调用其方法execute(); 

     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="mypac" extends="struts-default">
            <action name="index" class= "action.IndexAction" method="execute">
                <result name="success">/index.jsp</result>
                <result name="error">/error.jsp</result>
            </action>
       
         </package>
     </struts>
    <result name="success">/index.jsp</result>
    <result name="error">/error.jsp</result>

     调用其方法execute()后,就会返回一个字符串,根据对应的字符串找到对应的页面,返回给客户端(注:上面红色字体就是要和execute()返回的字符串相同才会找到对应页面

    Struts2的总结:

      struts2给我的带来的好处如下:

    1.获取表单内容,并组织生成参数对象
    2.根据请求的参数转发请求给适当的控制器
    3.在控制器中调用业务接口
    4.将业务接口返回的结果包装起来发送给指定的视图,并由视图完成处理结果的展现
    5.做一些简单的校验或是国际化工作

     二 spring4 的工作原理

      spring原理:

      内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟     xml Spring的配置文件来动态的创建对象,和调用对象里的方法的

       Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过  配置类达到的。  
          Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置 内部通过反射去动态的组装对象)  
          要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。  
    Spring里用的最经典的一个设计模式就是:模板方法模式。(这里我都不介绍了,是一个很常用的设计模式), Spring里的配置是很多的,很难都记住,但是Spring里的精华也无非就是以上的两点,把以上两点跟理解了 也就基本上掌握了Spring.

    在wed.xml配置(目的:启动spring 监听整个wed项目)

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>

    配置spring 配置文件如下:

    <?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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="    
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd  
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
                http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd  
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
    
        <!-- 引入外部属性文件 -->
        <context:property-placeholder location="classpath:jdbc.properties" />
    
        <bean id="mySessionFactory"
            class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
            <!-- 注入连接池,包含了数据库用户名,密码等等信息 -->
            <property name="dataSource" ref="myDataSource" />
    
            <!-- 配置Hibernate的其他的属性 -->
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.connection.autocommit">false</prop>
                    <!-- 开机自动生成表 -->
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                </props>
            </property>
            <property name="mappingResources">
                <list>
                    <value>news/entity/News.hbm.xml</value>
                </list>
            </property>
    
        </bean>
    
        <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driver}" />
            <property name="jdbcUrl" value="${jdbc.url}" />
            <property name="user" value="${jdbc.user}" />
            <property name="password" value="${jdbc.password}" />
            <!-- 每300秒检查所有连接池中的空闲连接 -->
            <property name="idleConnectionTestPeriod" value="300"></property>
            <!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 -->
            <property name="maxIdleTime" value="900"></property>
            <!-- 最大连接数 -->
            <property name="maxPoolSize" value="2"></property>
    
        </bean>
        
        <bean id="myNewsAction" class="news.action.NewsAction" scope="prototype">
            <property name="ns" ref="myNewsService"></property>
        </bean>
        
        <bean id="myNewsService" class="news.service.NewsServiceImpl" scope="prototype">
            <property name="nd" ref="myNewsDao"></property>
        </bean>
        
        <bean id="myNewsDao" class="news.dao.NewsDaoImpl" scope="prototype">
            <property name="sf" ref="mySessionFactory"></property>
        </bean>    
    </beans>
                
    引入的外部属性文件(jdbc.properties)目的:为了就算不懂java代码的人也可以配置数据库
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/news
    jdbc.user=root
    jdbc.password=123456
    
    
    #oracle
    jdbc_oracle.driver=oracle.jdbc.driver.OracleDriver
    jdbc_oracle.url=jdbc:oracle:thin@127.0.0.1:1521:orcl
    jdbc_oracle.user=news
    jdbc_oracle.password=123456
    sprinng的配置文件的简化(目的:少写一些配置文件)

    实现方法通过spring的注解:

    我们可以发现下面这段代码是不是感觉比较复杂或者说不好看 ,我们可以通过注解代替它

     <bean id="myNewsAction" class="news.action.NewsAction" scope="prototype">
            <property name="ns" ref="myNewsService"></property>
        </bean>
        
        <bean id="myNewsService" class="news.service.NewsServiceImpl" scope="prototype">
            <property name="nd" ref="myNewsDao"></property>
        </bean>
        
        <bean id="myNewsDao" class="news.dao.NewsDaoImpl" scope="prototype">
            <property name="sf" ref="mySessionFactory"></property>
        </bean>    
    
    

    我们可以直接删除上面这些配置文件,再添加一个注解的解释器:很简单只需配置一句:<context:component-scan base-package="news"></context:component-scan>(注:news 是须要注解类所在的包名,或者包名的前置)


    上面只列举了在dao中的注解,我们还需要在action、service里也使用同样的方法添加注解。这里就不一一举例了。   

        1.@Controller注解--定义控制器(类级别上的注解)action)

          2.@service注解--定义业务处理类(service)

          3.@repository注解--定义底层数据库处理接口(dao)

          4.@Resource注解--实现注入(jdk)

          5.@Scope("prototype")--//非单例

    三 hibernate 的核心与原理

    Hibernate是开源的一个ORM(对象关系映射)框架

    
    

          ORM,即Object-Relational Mapping,它的作用就是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。

    
    

     Hibernate的核心:

    Hibernate的优/缺点:

     优点:

    1、更加对象化

          以对象化的思维操作数据库,我们只需要操作对象就可以了,开发更加对象化。

    2、移植性
          因为Hibernate做了持久层的封装,你就不知道数据库,你写的所有的代码都具有可复用性。

    3、Hibernate是一个没有侵入性的框架,没有侵入性的框架我们称为轻量级框架。

          对比Struts的Action和ActionForm,都需要继承,离不开Struts。Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。

    4、Hibernate代码测试方便。

    5、提高效率,提高生产力。

    缺点:

    1、使用数据库特性的语句,将很难调优

    2、对大批量数据更新存在问题

    3、系统中存在大量的攻击查询功能

    四 Spring声明式事务

    1.什么是声明式事务?

      声明式事务(declarative transaction management)是spring提供的对程序事务管理的方式之一。Spring的声明式事务就是采用声明的方式来处理事务,用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要更改事务管理,也只需要在定义的配置文件中修改配置即可,在不需要事务管理的时候,只要在配置文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。

    2.首先我们看看手动写事务如下图:

    由上图可以看出,首先我们需要建立一个新的session.openSession(),其次通过session的getTransaction().begin()方法和getTransaction().commit()方法进行事务创建和事务提交,并且需要关闭session.close(),这样一来我们每次调用这个方法都会重新创建一个新的session,都要反复的做一样的事情,这样就不符合我们的软件工程设计思想,接下来我们使用声明式事务管理方式进行对代码的简化和调整

    使用springAOP声明式事务管理。

    1.首先我们要到aop的jar包

    2.然后在application.xml配置文件中进行事务配置:

    <!--配置事务  -->
        <!--配置Hibernate的局部事务管理器,使用HibernateTransactionManager类  -->
        <!--该类实现PlatformTransactionManager 接口,是针对Hibernate的特定实现  -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <!--配置HibernateTransactionManager时须要注入SessionFactory的引用  -->
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
        
        <!--配置事务的增强处理,指定事务管理器  -->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="del*" propagation="REQUIRED" />
                <tx:method name="mod*" propagation="REQUIRED" />
                <tx:method name="*" propagation="REQUIRED" read-only="true" />
            </tx:attributes>
        </tx:advice>
        
        <aop:config>
            <aop:pointcut id="interceptorPointCuts"
                expression="execution(*   
            dao.*.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" />
        </aop:config>

    将上图dao的代码进行修改 将session.openSession()改成getCurrentSessionn(); 由Spring去帮我们去启动事务去管理。

    2、使用@Transactional注解方式。

    首先在application.xml配置文件里配置@Transactional注解的解析器具体如下:

    <!--配置事务  -->
        <!--配置Hibernate的局部事务管理器,使用HibernateTransactionManager类  -->
        <!--该类实现PlatformTransactionManager 接口,是针对Hibernate的特定实现  -->
        <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            <!--配置HibernateTransactionManager时须要注入SessionFactory的引用  -->
            <property name="sessionFactory" ref="sessionFactory"></property>
        </bean>
        <!--解析事务注解  -->
        <tx:annotation-driven transaction-manager="transactionManager"/>
        

    接下来就注意里 这里的注解不是写在dao层 而是写在service层,应为是service调用了dao 大家千万注意了 具体如下:

      

  • 相关阅读:
    Echars折线配置详解
    Echarts中太阳图(Sunburst)的实例
    MongoDB shell 介绍
    js深度克隆对象
    js将有父子关系的数据转换成树形结构数据
    使用Mongoose类库实现简单的增删改查
    MongoDB可视化工具--Robo 3T 使用教程
    go语言之进阶篇并行和并发的区别与go语言并发优势
    go语言之进阶篇拷贝文件案例
    go语言之进阶篇借助bufio实现按行读取内容
  • 原文地址:https://www.cnblogs.com/zhaowancheng/p/5990914.html
Copyright © 2020-2023  润新知