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 大家千萬注意了 具體如下:

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM