SSH(struts2,spring4,hibernate5)詳解

使用ssh框架的目的:java

  將典型的J2EE結構,分爲表現層、中間層(業務邏輯層)和數據服務層。三層體系將業務規則、數據訪問及合法性校驗等工做放在中間層處理。客戶端不直接與數據庫交互,而是經過組件與中間層創建鏈接,再由中間層與數據庫交互。mysql

 

 struts2的核心與工做原理
web

    在學習struts2以前,首先咱們要明白使用struts2的目的是什麼?它能給咱們帶來什麼樣的好處?spring

 

設計目標

 

    Struts設計的第一目標就是使MVC模式應用於web程序設計。sql

 

mvc的好處:數據庫

 利於批量生產、規模生產、相互協做、推廣普及。express

mvc的壞處:apache

 不利個案創做、獨立創做、難藝術化、難個性化。編程

技術優點

    Struts2有兩方面的技術優點,一是全部的Struts2應用程序都是基於client/server HTTP交換協議,The JavaServlet API揭示了Java Servlet只是Java API的一個很小子集,這樣咱們能夠在業務邏輯部分使用功能強大的Java語言進行程序設計。設計模式

    二是提供了對MVC的一個清晰的實現,這一實現包含了不少參與對因此請求進行處理的關鍵組件,如:攔截器、OGNL表達式語言、堆棧。

 

 由於struts2有這樣目標,而且有這樣的優點,因此,這是咱們學習struts2的理由,下面,咱們在深刻剖析一下struts的工做原理。

工做原理

Suruts2的工做原理能夠用下面這張圖來描述:

  

 一個請求在Struts2框架中的處理大概分爲如下幾個步驟 :

  一、客戶端初始化一個指向Servlet容器(例如Tomcat)的請求

  二、這個請求通過一系列的過濾器(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的優/缺點:

 優勢:

一、更加對象化

      以對象化的思惟操做數據庫,咱們只須要操做對象就能夠了,開發更加對象化。

二、移植性
      由於Hibernate作了持久層的封裝,你就不知道數據庫,你寫的全部的代碼都具備可複用性。

三、Hibernate是一個沒有侵入性的框架,沒有侵入性的框架咱們稱爲輕量級框架。

      對比Struts的Action和ActionForm,都須要繼承,離不開Struts。Hibernate不須要繼承任何類,不須要實現任何接口。這樣的對象叫POJO對象。

四、Hibernate代碼測試方便。

五、提升效率,提升生產力。

 

缺點:

一、使用數據庫特性的語句,將很難調優

二、對大批量數據更新存在問題

三、系統中存在大量的攻擊查詢功能

 

四 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去幫咱們去啓動事務去管理。

二、使用@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 你們千萬注意了 具體以下:

相關文章
相關標籤/搜索