天天看點

應用架構@SSM架構原理,作用及使用方法

1 架構原理

(一)SSM 作用

SSM 架構是 spring MVC ,spring 和 mybatis 架構的整合,是标準的 MVC 模式,将整個系統劃分為表現層,controller層,service 層,DAO 層四層;

  • 使用spring MVC負責請求的轉發和視圖管理
  • spring實作業務對象管理
  • mybatis作為資料對象的持久化引擎

(二)實作原理

  • spring MVC
    • DNS 負責域名的解析, 比如通路www.baidu.com 先找到DNS擷取相應的伺服器IP和端口;
    • 請求消息到達端口以後由TOMCAT主動去詢問自己占用的端口是否由請求發來;
    • 如果有請求TOMCAT交給對應的項目處理;
    • 用戶端發送請求到 DispacherServlet(前端控制器即分發器),這裡可以設定攔截器,對請求進行過濾處理;
    • 由 DispacherServlet 控制器查詢 HanderMapping,通過解析請求,判斷請求希望執行的具體方法,即找到處理請求的 Controller;

      這個map表由很多key:value鍵值對組成, key值是controller的名字(@mapping ...), value值是該controller所在類的位址和方法簽名;

      (一個類中可能由很多controller)這個找到controller位置并執行個體化的過程叫做反射

      反射得到執行個體後通過代理執行相應的方法即相應controller;

    • 通過 HandlerAdapter 調用具體的 Controller 方法;
    • Controller 調用業務邏輯處理後,傳回 ModelAndView,即控制器結果傳回給視圖解析器;
    • DispacherServlet 查詢視圖解析器,找到ModelAndView 指定的視圖
    • 視圖負責将結果顯示到用戶端
應用架構@SSM架構原理,作用及使用方法

上面補充:

  • 攔截器:攔截器主要是在 SpringMVC 的 controller 處理請求之前,對請求做一些處理,攔截器攔截的是 Controller,攔截器分為:HandlerInterceptro(springmvc 的)和 WebRequestInterceptor(spring 的),同時裡面一共有三個方法,可以實作部分,主要是攔截位置不同,整體的指向順序為: preHandle ->進入控制器(controller)-> postHandler -> JSP -> afterCompletion;
  • 配置檔案
    • web.xml:在 中要配置前端控制器,springmvc 的配置檔案位置、自啟動、攔截器以及編碼過濾器;
    • springmvc.xml :配置掃描包,即項目中所有 controller 位置,配置注解驅動(一般使用注解),配置不要攔截靜态資源、自定義視圖解析器(就是前字尾,可以和 controller 的傳回值相連接配接,構成完整的頁面路徑);
    • controller 中代碼示例:
@controller // 将該類交給容器管理
public class demo(){
    @RequestMapping("A")
    public String hello(){
        return "main";
    }
    @RequestMapping("B")
    public String hello(){
        return "main";
    }
}
           

然後在 jsp 的例如表單中的 action 屬性配置為:A,将這個請求和控制器進行映射了,這個請求對應會調用 hello 這個控制器;

  • 同時 springmvc 将 jsp 中的參數值傳遞給 controller 中可以采用方法有:
    • HandlerMenthod;
    • Map
    • Model 接口
    • ModelAndView 類
  • Spring:我們平時開發接觸最多的估計就是IOC容器,它可以裝載bean(也就是我們Java中的類,當然也包括service dao裡面的),有了這個機制,我們就不用在每次使用這個類的時候為它初始化,很少看到關鍵字new。另外spring的aop,事務管理等等都是我們經常用到的。
  • Mybatis:mybatis是對jdbc的封裝,它讓資料庫底層操作變的透明。mybatis的操作都是圍繞一個sqlSessionFactory執行個體展開的。mybatis通過配置檔案關聯到各實體類的Mapper檔案,Mapper檔案中配置了每個類對資料庫所需進行的sql語句映射。在每次與資料庫互動時,通過sqlSessionFactory拿到一個sqlSession,再執行sql指令。

(三)使用方法

要完成一個功能:

  • 先寫實體類entity,定義對象的屬性,(可以參照資料庫中表的字段來設定,資料庫的設計應該在所有編碼開始之前)。
  • 寫Mapper.xml(Mybatis),其中定義你的功能,對應要對資料庫進行的那些操作,比如 insert、selectAll、selectByKey、delete、update等。
  • 寫Mapper.java,将Mapper.xml中的操作按照id映射成Java函數。
  • 寫Service.java,為控制層提供服務,接受控制層的參數,完成相應的功能,并傳回給控制層。
  • 寫Controller.java,連接配接頁面請求和服務層,擷取頁面請求的參數,通過自動裝配,映射不同的URL到相應的處理函數,并擷取參數,對參數進行處理,之後傳給服務層。
  • 寫JSP頁面調用,請求哪些參數,需要擷取什麼資料。

DataBase --> Entity --> Mapper.xml --> Mapper.Java --> Service.java --> Controller.java --> .Jsp

說明:

  • Spring MVC 擁有控制器,作用跟Struts2 類似,接收外部請求,解析參數傳給服務層
  • Spring 容器屬于協調上下文,管理對象間的依賴,提供事務機制
  • mybatis 屬于orm持久層架構,将業務實體與資料表聯合起來;
  • Spring MVC 控制層,想當于 Struts的作用
  • Spring 控制反轉和依賴注入: 建立對象交由容器管理,達到了解耦的作用
  • mybatis 主要用來操作資料庫(資料庫的增删改查)
  • IOC:控制反轉,是一種降低對象之間耦合關系的設計思想,面試的時候最好能說出來個例子,加深了解。例子:租房子,以前租房子需要一個房子一個房子找,費時費力,然後現在加入一個房屋中介,把你需要的房型告訴中介,就可以直接選到需要的房子,中介就相當于spring容器。
  • AOP:面向切面程式設計,是面向對象開發的一種補充,它允許開發人員在不改變原來模型的基礎上動态的修改模型以滿足新的需求,如:動态的增加日志、安全或異常處理等。AOP使業務邏輯各部分間的耦合度降低,提高程式可重用性,提高開發效率。

持久層(資料通路層)

  • DAO層:DAO層主要是做資料持久層的工作,負責與資料庫進行聯絡的一些任務都封裝在此,
    • DAO層的設計首先是設計DAO的接口,
    • 然後在Spring的配置檔案中定義此接口的實作類,
    • 然後就可在子產品中調用此接口來進行資料業務的處理,而不用關心此接口的具體實作類是哪個類,顯得結構非常清晰,
    • DAO層的資料源配置,以及有關資料庫連接配接的參數都在Spring的配置檔案中進行配置。

業務邏輯層

  • Service層:Service層主要負責業務子產品的邏輯應用設計。
    • 首先設計接口,再設計其實作的類
    • 接着再在Spring的配置檔案中配置其實作的關聯。這樣我們就可以在應用中調用Service接口來進行業務處理。
    • Service層的業務實作,具體要調用到已定義的DAO層的接口,
    • 封裝Service層的業務邏輯有利于通用的業務邏輯的獨立性和重複利用性,程式顯得非常簡潔。

表現控制層

  • Controller層:Controller層負責具體的業務子產品流程的控制,
    • 在此層裡面要調用Service層的接口來控制業務流程,
    • 控制的配置也同樣是在Spring的配置檔案裡面進行,針對具體的業務流程,會有不同的控制器,我們具體的設計過程中可以将流程進行抽象歸納,設計出可以重複利用的子單元流程子產品,這樣不僅使程式結構變得清晰,也大大減少了代碼量。

View層

  • View層 此層與控制層結合比較緊密,需要二者結合起來協同工發。View層主要負責前台jsp頁面的表示.

各層聯系

  • DAO層,Service層這兩個層次都可以單獨開發,互相的耦合度很低,完全可以獨立進行,這樣的一種模式在開發大項目的過程中尤其有優勢
  • Controller,View層因為耦合度比較高,因而要結合在一起開發,但是也可以看作一個整體獨立于前兩個層進行開發。這樣,在層與層之前我們隻需要知道接口的定義,調用接口即可完成所需要的邏輯單元應用,一切顯得非常清晰簡單。
  • Service邏輯層設計
    • Service層是建立在DAO層之上的,建立了DAO層後才可以建立Service層,而Service層又是在Controller層之下的,因而Service層應該既調用DAO層的接口,又要提供接口給Controller層的類來進行調用,它剛好處于一個中間層的位置。每個模型都有一個Service接口,每個接口分别封裝各自的業務處理方法。

2 Spring部分

(一)Spring的運作流程

  • 第一步:加載spring 配置檔案

    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    ,ApplicationContext接口,它由BeanFactory接口派生而來,因而提供了BeanFactory所有的功能。配置檔案中的bean的資訊是被加載在HashMap中的,一個bean通常包括,id,class,property等,bean的id對應HashMap中的key,value呢就是bean

具體如何加載?源碼如下:

if (beanProperty.element("map") != null){  
Map<String, Object> propertiesMap = new HashMap<String, Object>();  
Element propertiesListMap = (Element)beanProperty.elements().get(0);  
Iterator<?> propertiesIterator = propertiesListMap .elements().iterator();  
while (propertiesIterator.hasNext()) {  
	Element vet = (Element) propertiesIterator.next();  
	if(vet.getName().equals("entry")) {  
		String key = vet.attributeValue("key");  
		Iterator<?> valuesIterator = vet.elements()  .iterator();  
		while (valuesIterator.hasNext()) {  
			Element value = (Element) valuesIterator.next();  
			if (value.getName().equals("value")){  
				propertiesMap.put(key, value.getText());  
			}  
			if (value.getName().equals("ref")) {  
				propertiesMap.put(key, new String[]{
						value.attributeValue("bean") 
						});  
			}  
		}  
	}  
}  
bean.getProperties().put(name, propertiesMap);  
} 
           
  • 第二步:調用getBean方法,getBean是用來擷取applicationContext.xml檔案裡bean的,()寫的是bean的id。一般情況都會強轉成我們對應的業務層(接口)。例如

    SpringService springService =(SpringService)ac.getBean("Service");

  • 第三步:這樣我們就可以調用業務層(接口實作)的方法。

具體如下:

應用架構@SSM架構原理,作用及使用方法

Java反射博大精深,我也不很懂,具體請檢視Java基礎之—反射

那麼bean中的東西到底是怎麼注入進去的?簡單來講,就是在執行個體化一個bean時,實際上就執行個體化了類,它通過反射調用類中set方法将事先儲存在HashMap中的類屬性注入到類中。這樣就回到了我們Java最原始的地方,對象.方法,對象.屬性

(二)Spring的原理

  • 什麼是spring?
  • spring是一個容器架構,它可以接管web層,業務層,dao層,持久層的各個元件,并且可以配置各種bean, 并可以維護bean與bean的關系,當我們需要使用某個bean的時候,我們可以直接getBean(id),使用即可
  • Spring目的:就是讓對象與對象(子產品與子產品)之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(Spring根據這些配置 内部通過反射去動态的組裝對象) ,Spring是一個容器,凡是在容器裡的對象才會有Spring所提供的這些服務和功能。
  • 層次架構圖:
    應用架構@SSM架構原理,作用及使用方法
    說明:
  • web層: struts充當web層,接管jsp,action,表單,主要展現出mvc的資料輸入,資料的處理,資料的顯示分離
    • model層: model層在概念上可以了解為包含了業務層,dao層,持久層,需要注意的是,一個項目中,不一定每一個層次都有
    • 持久層:展現oop,主要解決關系模型和對象模型之間的阻抗

(三)Spring的核心技術

  • IOC
    • ioc(inverse of control)控制反轉: 所謂反轉就是把建立對象(bean)和維護對象(bean)之間的關系的權利從程式轉移到spring的容器(spring-config.xml)
      應用架構@SSM架構原理,作用及使用方法
      說明:

      <bean></bean>

      這對标簽元素的作用:當我們加載spring架構時,spring就會自動建立一個bean對象,并放入記憶體相當于我們正常的new一個對象,而

      <property></property>

      中的value則是實作了“對象.set方法”,這裡也展現了注入了概念
  • DI
    • di(dependency injection)依賴注入: 實際上di和ioc是同一個概念,spring的設計者,認為di更準确的表示spring的核心
    • spring提倡接口程式設計,在配合di技術就可以達到層與層解耦的目的,為什麼呢?因為層與層之間的關聯,由架構幫我們做了,這樣代碼之間的耦合度降低,代碼的複用性提高
    • 接口程式設計的好處請通路Java中接口程式設計的好處以及實作方式的選擇?
  • AOP
    • aspect oriented programming(面向切面程式設計)
    • 核心:在不增加代碼的基礎上,還增加新功能
    • 了解:面向切面:其實是,把一些公共的“東西”拿出來,比如說,事務,安全,日志,這些方面,如果你用的到,你就引入。 也就是說:當你需要在執行一個操作(方法)之前想做一些事情(比如,開啟事務,記錄日志等等),那你就用before,如果想在操作之後做點事情(比如,關閉一些連接配接等等),那你就用after。其他類似

(四)spring整體架構圖

![spring整體架構圖]](https://img2018.cnblogs.com/blog/763048/202001/763048-20200101101529937-1096176913.png)

***1、core container(核心容器) ***

核心容器包含了core,beans,context和expression language四個子產品

core和beans子產品是架構的基礎部分,提供IOC和依賴注入特性。這裡的基礎概念是BeanFactory,它提供對Factory模式的經典實作來消除對程式性單例模式的需要,并真正地允許你從程式邏輯中分離出依賴關系和配置。

  • core子產品主要包含了spring架構基本的黑犀牛工具類,spring的其他組建都要用到這個包裡的類,core子產品是其他元件的基本核心。當然你也可以在自己應用系統中使用這些工具類。
  • beans子產品是所有應用都要用到的,它包含通路配置檔案,建立和管理bean以及進行ioc,di操作相關的所有類
  • context子產品建構與core和beans子產品基礎之上,提供了一種類似于JNDI注冊器的架構式的對象通路方法。context子產品繼承了beans的特性,為spring核心提供了大量擴充,添加了對國際化(例如資源綁定)、事件傳播、資源加載和對context的透明建立的支援。context子產品同僚也支援j2ee的一些特性,例如EJB,JMX和基礎的遠端處理,applicationContext接口是context子產品的關鍵。
  • ExpressionLanguage子產品提供了強大的表達式語言,用于在運作時查詢和操縱對象。他是jsp2.1規範中定義的unifed expression language的擴充。該語言支援設定/擷取屬性的值,屬性的配置設定,方法的調用 ,通路數組上下文,容器和索引器,邏輯和算數運算符,命名變量以及從spring的ioc容器中根據名稱檢索對象。它也支援list投影,選擇和一般的list聚合

***2、Date Access/Integration ***

Date Access/Integration層包含JDBC,ORM,OXM,JMS和Transaction子產品

  • jdbc子產品提供了一個jdbc抽象層,他可以消除冗長的jdbc編碼和解析資料廠商特有的錯誤代碼。這個子產品包含了spring對jdbc資料通路進行封裝的所有類。
  • orm子產品為流行的對象-關系映射API,如JPA,JDO,Hibernate,iBatis等,提供了一個互動層。利用ORM封裝包,可以混合使用所有spring提供的特性進行O/R映射,如前邊提到的簡單聲明性事務管理。spring架構插入了若幹個ORM架構 ,進而提供了ORM的對象關系工具,其中包括JDO,hibernate和iBatisSQl Map。所有這些都遵從spring的通用事務和DAO異常層次結構。
  • OXM子產品提供了一個對Object/XML映射實作的抽象層,Object/XML映射實作包括JAXB,Castor,XMLBeans,JiBX和XStream。
  • JMS(java massage service)子產品主要包含了一些制造和消費消息的特性
  • Transaction子產品支援程式設計和聲明性的事務管理,這些事務類必須實作特地的接口。并且對多有的POJO都适用

***3、web ***

web上下文子產品建立在應用程式上下文子產品之上,為基于web的應用程式提供了上下文。是以,spring架構支援與Jakarta struts的內建。web子產品還簡化了處理大部分請求以及将請求參數綁定到域對象的工作。web層包含了web,web-servlet,web-Struts 和web-porlet

  • web子產品,提供了基礎的面向web的內建特性。例如:多檔案上傳,使用servlet listeners初始化 Ioc容器已經一個面向web的應用上下文。它還包含spring遠端支援中的web的相關部分。
  • web-servlet子產品web.servlet.jar:該子產品包含spring的model-view-controller(mvc)實作。spring的mbc架構使得模型範圍内的代碼和webforms之間能夠清楚地分離出來。并與spring架構的其他特性內建在一起。
  • web-Struts子產品,該子產品提供了對struts的支援,使得類在spring應用中能夠與一個典型的struts web層內建在一起。注意,該支援在spring3.0中已被棄用。
  • web-portlet子產品,提供了用于portlet環境和web-servlet子產品的MVC的實作。

***4、AOP ***

aop子產品提供了一個符合aop聯盟标準的面向切面程式設計的實作,它讓你可以定義例如方法攔截器和切點,進而将邏輯代碼分開,降低它們之間的耦合性。利用source-level的中繼資料功能,還可以将各種行為資訊合并到你的代碼中,這有點像.Net技術中的attribute概念

通過配置管理特性,springAop子產品直接将面向界面的程式設計功能內建到了spring架構中,是以可以很容易地使用spring架構管理的任何對象支援aop,springAop子產品為基于spring的應用程式中的對象提供了事務管理服務。通過使用springAop,不用曆來EJB元件,就可以将聲明性事務管理內建到應用程式中。

  • Aspects子產品提供了AspectJ的內建支援。
  • Instrumentation子產品提供了class Instrumentation支援和classloader實作,使用可以再特定的應用伺服器上使用。

***5、Test ***

test子產品支援使用JUnit和TestNG對spring元件進行測試。

3 Spring MVC部分

(一)Spring MVC的運作流程

  • springMVC架構
    應用架構@SSM架構原理,作用及使用方法
    架構執行流程(面試必問)
    • 1、使用者發送請求至前端控制器DispatcherServlet
    • 2、DispatcherServlet收到請求調用HandlerMapping處理器映射器。
    • 3、處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一并傳回給DispatcherServlet。
    • 4、DispatcherServlet通過HandlerAdapter處理器擴充卡調用處理器
    • 5、執行處理器(Controller,也叫後端控制器)。
    • 6、Controller執行完成傳回ModelAndView
    • 7、HandlerAdapter将controller執行結果ModelAndView傳回給DispatcherServlet
    • 8、DispatcherServlet将ModelAndView傳給ViewReslover視圖解析器
    • 9、ViewReslover解析後傳回具體View
    • 10、DispatcherServlet對View進行渲染視圖(即将模型資料填充至視圖中)。
    • 11、DispatcherServlet響應使用者

(二)Spring MVC的原理

  • 1、什麼是SpringMVC?
  • springmvc是spring架構的一個子產品,springmvc和spring無需通過中間整合層進行整合。
  • springmvc是一個基于mvc的web架構。
    應用架構@SSM架構原理,作用及使用方法
  • mvc
    • mvc在b/s系統 下的應用:
      應用架構@SSM架構原理,作用及使用方法
    • 前端控制器DispatcherServlet(不需要程式員開發)
      • 作用接收請求,響應結果,相當于轉發器,中間處理器。有了DispatcherServlet減少了其它元件之間的耦合度。
    • 處理器映射器HandlerMapping(不需要程式員開發)
      • 作用:根據請求的url查找Handler
    • 處理器擴充卡HandlerAdapter
      • 作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
    • 處理器Handler (需要程式員開發)
      • 注意:編寫Handler時按照HandlerAdapter的要求去做,這樣擴充卡才可以去正确執行Handler
    • 視圖解析器View resolver(不需要程式員開發)
      • 作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
    • 視圖View (需要程式員開發)
      • View是一個接口,實作類支援不同的View類型(jsp、freemarker、pdf…)
  • struts2與springMVC的差別?

1、Struts2是類級别的攔截,一個類對應一個request 上下文, SpringMVC是方法級别的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,,是以說從架構本身上SpringMVC就容易實作restful url,而struts2的架構實作起來要費勁,因為Struts2中Action的一個方法可以對應一個url ,而其類屬性卻被所有方法共享,這也就無法用注解或其他方式辨別其所屬方法了。

2、由上邊原因, SpringMVC的方法之間基本上獨立的,獨享request response資料,請求資料通過參數擷取,處理結果通過ModelMap交回給架構,方法之間不共享變量,而Struts2搞的就比較亂,雖然方法之間也是獨立的,但其所有Action變量是共享的,這不會影響程式運作,卻給我們編碼讀程式時帶來麻煩,每次來了請求就建立一個Action ,一個Action對象對應一個request 上下文。

3、由于Struts2需要針對每個request進行封裝,把request , session等servlet生命周期的變量封裝成一個一 個Map ,供給每個Action使用,并保證線程安全,是以在原則上,是比較耗費記憶體的。

4、攔截器實作機制上, Struts2有以自己的interceptor機制, SpringMVC用的是獨立的AOP方式,這樣導緻Struts2的配置檔案量還是比SpringMVC大。

5、SpringMVC的入口是servlet ,而Struts2是filter (這裡要指出, filter和servlet是不同的。以前認為filter是servlet的一種特殊),這就導緻 了二者的機制不同,這裡就牽涉到servlet和filter的差別了。

6、SpringMVC內建了Ajax ,使用非常友善,隻需一個注解@ResponseBody就可以實作,然後直接傳回響應文本即可,而Struts2攔截器內建了Ajax ,在Action中處理時一般必須安裝插件或者自己寫代碼內建進去,使用起來也相對不友善。

7、SpringMVC驗證支援JSR303 ,處理起來相對更加靈活友善,而Struts2驗證比較繁瑣,感覺太煩亂。

8、Spring MVC和Spring是無縫的。從這個項目的管理和安全上也比Struts2高(當然Struts2也可以通過不同的目錄結構和相關配置做到SpringMVC-樣的效果,但是需要xml配置的地方不少)。

9、設計思想上, Struts2更加符合0OP的程式設計思想,SpringMVC就比較謹慎,在servlet上擴充。

10、SpringMVC開發效率和性能高于Struts2。

11、SpringMVC可以認為已經100%零配置。

(三)Spring MVC的核心技術

  • 注解開發(@Controller,@RequestMapping,@ResponseBody。。。。)
    • 還有Spring的諸多注解,這兩者是不需要整合的~
  • 傳參,接參(request)
  • 基本配置
  • 檔案上傳與下載下傳
    • Spring MVC中檔案上傳需要添加Apache Commons FileUpload相關的jar包,
    • 基于該jar, Spring中提供了MultipartResolver實作類: CommonsMultipartResolver.
  • 攔截器
  • 其實最核心的還是SpringMVC的執行流程,各個點的作用得搞清楚。

4 Mybatis 部分

(一)Mybatis的運作流程

  • Mybatis運作流程圖:
    應用架構@SSM架構原理,作用及使用方法

第一步:配置檔案mybatis.xml,大體如下,

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 引入外部檔案
		resource:引入項目中配置檔案
		url:引入網絡中或者路徑檔案
	-->
    <properties resource="jdbc.properties"/>
    <settings>
        <!--<setting name="mapUnderscoreToCamelCase" value="true" />-->
        <setting name="lazyLoadingEnabled" value="true" />
        <setting name="aggressiveLazyLoading"  value="false" />
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.nuc.entity"></package>
    </typeAliases>
    <!-- - - - - - - 資料庫環境配置- - - - - - - - - -->
    <environments default="environments">
        <environment id="environments">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.jdbcUrl}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- - - - - - - -映射檔案路徑- - - - - - -->
    <mappers>
        <!--自動掃描包下的映射檔案,要求:同名,同目錄-->
        <package name="com.nuc.mapper" />
    </mappers>
</configuration>
           

第二步:加載我們的xml檔案

第三步:建立SqlSessionFactoryBuilder

第四步:建立SqlSessionFactory

第五步:調用openSession(),開啟sqlSession

第六步:getMapper()來擷取我們的mapper(接口),mapper對應的映射檔案,在加載mybatis.xml時就會加載

第七步:使用我們自己的mapper和它對應的xml來完成我們和資料庫互動。即增删改查。

第八步:送出session,關閉session。

代碼如下:

String resource = "mybatis-config.xml";
SqlSession sqlSession = null;
InputStream inputStream = Resources.getResourceAsStream(resource);//讀取mybatis配置檔案
//SqlSessionFactoryBuilder這個類的作用就是為了建立SqlSessionFactory的
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
/**
 *  factory.openSession(); //需手動送出事務
 *   factory.openSession(true); //系統自動送出事務
 */
sqlSession = factory.openSession();
CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);
//增删改查的操作
sqlSession.commit();//如果沒有送出,資料庫的資料不會改變
sqlSession.close();
           

需要注意的是,sqlSession也自帶一些資料互動的操作

(二)Mybatis的原理

  • 什麼是Mybatis?
    • mybatis專注sql本身,需要程式員自己編寫sql語句,sql修改、優化比較友善。mybatis是一個不完全 的ORM架構,雖然程式員自己寫sql,mybatis 也可以實作映射(輸入映射、輸出映射)。
    • mybatis是一個持久層的架構,是apache下的***項目。
    • mybatis托管到goolecode下,後來托管到github下:mybatis Github位址
    • mybatis讓程式将主要精力放在sql上,通過mybatis提供的映射方式,***靈活生成(半自動化,大部分需要程式員編寫sql)滿足需要sql語句。
    • mybatis可以将向 preparedStatement 中的輸入參數自動進行輸入映射,将查詢結果集靈活映射成java對象。(輸出映射)
  • mybatis底層實作
    • mybatis底層還是采用原生jdbc來對資料庫進行操作的,隻是通過 SqlSessionFactory,SqlSession Executor,StatementHandler,ParameterHandler,ResultHandler和TypeHandler等幾個處理器封裝了這些過程
  • 對原生态jdbc程式(單獨使用jdbc開發)問題總結:
    • 資料庫連接配接,使用時建立,不使用就關閉,對資料庫進行頻繁連接配接開啟和關閉,造成資料庫資源的浪費

      解決:使用資料庫連接配接池管理資料庫連接配接

    • 将sql 語句寫死到Java代碼中,如果sql語句修改,需要對java代碼重新編譯,不利于系統維護

      解決:将sql語句設定在xml配置檔案中,即使sql變化,也無需重新編譯

    • 向preparedStatement中設定參數,對占位符位置和設定參數值,寫死到Java檔案中,不利于系統維護

      解決:将sql語句及占位符,參數全部配置在xml檔案中

    • 從resutSet中周遊結果集資料時,存在寫死,将擷取表的字段進行寫死,不利于系統維護。

      解決:将查詢的結果集,自動映射成java對象

  • mybatis工作原理
    • mybatis通過配置檔案建立sqlsessionFactory,sqlsessionFactory根據配置檔案,配置檔案來源于兩個方面:一個是xml,一個是Java中的注解,擷取sqlSession。SQLSession包含了執行sql語句的所有方法,可以通過SQLSession直接運作映射的sql語句,完成對資料的增删改查和事物的送出工作,用完之後關閉SQLSession。

(三)Mybatis的核心技術

  • Mybatis輸入映射
    • 通過parameterType指定輸入參數的類型,類型可以是簡單類型、hashmap、pojo的包裝類型
  • Mybatis輸出映射
    • 一、resultType
      • 作用:将查詢結果按照sql列名pojo屬性名一緻性映射到pojo中。
      • 使用resultType進行輸出映射,隻有查詢出來的列名和pojo中的屬性名一緻,該列才可以映射成功。
      • 如果查詢出來的列名和pojo中的屬性名全部不一緻,則不會建立pojo對象。
      • 隻要查詢出來的列名和pojo中的屬性有一個一緻,就會建立pojo對象
      • 如果查詢出來的列名和pojo的屬性名不一緻,通過定義一個resultMap對列名和pojo屬性名之間作一個映射關系。
    • 二、resultMap
      • 使用association和collection完成一對一和一對多進階映射(對結果有特殊的映射要求)。
      • association:
        • 作用:将關聯查詢資訊映射到一個pojo對象中。
        • 場合:為了友善查詢關聯資訊可以使用association将關聯訂單資訊映射為使用者對象的pojo屬性中,比如:查詢訂單及關聯使用者資訊。
        • 使用resultType無法将查詢結果映射到pojo對象的pojo屬性中,根據對結果集查詢周遊的需要選擇使用resultType還是resultMap。
      • collection:
        • 作用:将關聯查詢資訊映射到一個list集合中。
        • 場合:為了友善查詢周遊關聯資訊可以使用collection将關聯資訊映射到list集合中,比如:查詢使用者權限範圍子產品及子產品下的菜單,可使用collection将子產品映射到子產品list中,将菜單清單映射到子產品對象的菜單list屬性中,這樣的作的目的也是友善對查詢結果集進行周遊查詢。如果使用resultType無法将查詢結果映射到list集合中。
  • Mybatis的動态sql
  • 什麼是動态sql?
    • mybatis核心 對sql語句進行靈活操作,通過表達式進行判斷,對sql進行靈活拼接、組裝。
    • 包括, where ,if,foreach,choose,when,otherwise,set,trim等标簽的使用
  • 資料模型分析思路
  • 1、每張表記錄的資料内容

    * 分子產品對每張表記錄的内容進行熟悉,相當 于你學習系統 需求(功能)的過程

    • 2、每張表重要的字段設定
      • 非空字段、外鍵字段
  • 3、資料庫級别表與表之間的關系
    • 外鍵關系
  • 4、表與表之間的業務關系
    • 在分析表與表之間的業務關系時一定要建立 在某個業務意義基礎上去分析。\color{red}{在某個業務意義基礎上去分析。}在某個業務意義基礎上去分析。

5 架構整合示例

下面主要介紹三大架構的整合,至于環境的搭建以及項目的建立,參看上面的博文。這次整合我分了2個配置檔案,分别是spring-mybatis.xml,包含spring和mybatis的配置檔案,還有個是spring-mvc的配置檔案,此外有2個資源檔案:jdbc.propertis和log4j.properties。完整目錄結構如下:

應用架構@SSM架構原理,作用及使用方法

使用架構的版本:

Spring 4.0.2 RELEASE

Spring MVC 4.0.2 RELEASE

MyBatis 3.2.6

1 Maven引入需要的JAR包

在pom.xml中引入jar包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.moyue.maven01</groupId>
    <artifactId>maven01</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>maven01 Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>  
        <!-- spring版本号 -->  
        <spring.version>4.0.2.RELEASE</spring.version>  
        <!-- mybatis版本号 -->  
        <mybatis.version>3.2.6</mybatis.version>  
        <!-- log4j日志檔案管理包版本 -->  
        <slf4j.version>1.7.7</slf4j.version>  
        <log4j.version>1.2.17</log4j.version>  
    </properties> 

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
             <!-- 表示開發的時候引入,釋出的時候不會加載此包 -->  
            <scope>test</scope>
        </dependency>
        <!-- <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency> -->

         <!-- =======spring核心包 ========= -->  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-core</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-web</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-oxm</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-tx</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-jdbc</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-webmvc</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-aop</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context-support</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-test</artifactId>  
            <version>${spring.version}</version>  
        </dependency>  


        <!-- =========  mybatis核心包  ================= -->  
        <dependency>  
            <groupId>org.mybatis</groupId>  
            <artifactId>mybatis</artifactId>  
            <version>${mybatis.version}</version>  
        </dependency>  
         <!-- mybatis/spring包 -->  
        <dependency>  
            <groupId>org.mybatis</groupId>  
            <artifactId>mybatis-spring</artifactId>  
            <version>1.2.2</version>  
        </dependency>  

         <!-- 導入java ee jar 包 -->  
        <dependency>  
            <groupId>javax</groupId>  
            <artifactId>javaee-api</artifactId>  
            <version>7.0</version>  
        </dependency>  

         <!-- 導入Mysql資料庫連結jar包 -->  
        <dependency>  
            <groupId>mysql</groupId>  
            <artifactId>mysql-connector-java</artifactId>  
            <version>5.1.36</version>  
        </dependency>  
        <!-- 導入dbcp的jar包,用來在applicationContext.xml中配置資料庫 -->  
        <dependency>  
            <groupId>commons-dbcp</groupId>  
            <artifactId>commons-dbcp</artifactId>  
            <version>1.2.2</version>  
        </dependency>  

        <!-- JSTL标簽類 -->  
        <dependency>  
            <groupId>jstl</groupId>  
            <artifactId>jstl</artifactId>  
            <version>1.2</version>  
        </dependency>  
        <!-- 日志檔案管理包 -->  
        <!-- log start -->  
        <dependency>  
            <groupId>log4j</groupId>  
            <artifactId>log4j</artifactId>  
            <version>${log4j.version}</version>  
        </dependency>  

        <!-- 格式化對象,友善輸出日志 -->  
        <dependency>  
            <groupId>com.alibaba</groupId>  
            <artifactId>fastjson</artifactId>  
            <version>1.1.41</version>  
        </dependency>  

        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-api</artifactId>  
            <version>${slf4j.version}</version>  
        </dependency>  

        <dependency>  
            <groupId>org.slf4j</groupId>  
            <artifactId>slf4j-log4j12</artifactId>  
            <version>${slf4j.version}</version>  
        </dependency>  
        <!-- log end -->  
        <!-- 映入JSON -->  
        <dependency>  
            <groupId>org.codehaus.jackson</groupId>  
            <artifactId>jackson-mapper-asl</artifactId>  
            <version>1.9.13</version>  
        </dependency>  
        
        <!-- ====上傳元件包======== -->  
        <dependency>  
            <groupId>commons-fileupload</groupId>  
            <artifactId>commons-fileupload</artifactId>  
            <version>1.3.1</version>  
        </dependency>  
        <dependency>  
            <groupId>commons-io</groupId>  
            <artifactId>commons-io</artifactId>  
            <version>2.4</version>  
        </dependency>  
        <dependency>  
            <groupId>commons-codec</groupId>  
            <artifactId>commons-codec</artifactId>  
            <version>1.9</version>  
        </dependency>  

    </dependencies>

    <build>
        <finalName>maven01</finalName>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.8.v20150217</version>
                <configuration>
                    <httpConnector>
                        <port>80</port>
                    </httpConnector>
                    <stopKey>shutdown</stopKey>
                    <stopPort>9966</stopPort>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
           

2 整合SpringMVC

2.1 配置spring-mvc.xml

配置裡面的注釋也很詳細,主要是自動掃描控制器,視圖模式,注解的啟動這三個。

<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
    <!-- 自動掃描該包,使SpringMVC認為包下用了@controller注解的類是控制器 -->  
    <context:component-scan base-package="com.moyue.controller" />  
    <!-- 擴充了注解驅動,可以将請求參數綁定到控制器參數 -->
    <mvc:annotation-driven/>
    <!-- 靜态資源處理  css js imgs -->
    <mvc:resources location="/resources/**" mapping="/resources"/>

    <!--避免IE執行AJAX時,傳回JSON出現下載下傳檔案 -->  
    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
        <property name="supportedMediaTypes">  
            <list>  
                <value>text/html;charset=UTF-8</value>  
            </list>  
        </property>  
    </bean>  
    <!-- 啟動SpringMVC的注解功能,完成請求和注解POJO的映射 -->  
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
            <list>  
                <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON轉換器 -->  
            </list>  
        </property>  
    </bean>  

    <!-- 配置檔案上傳,如果沒有使用檔案上傳可以不用配置,當然如果不配,那麼配置檔案中也不必引入上傳元件包 -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
        <!-- 預設編碼 -->  
        <property name="defaultEncoding" value="utf-8" />    
        <!-- 檔案大小最大值 -->  
        <property name="maxUploadSize" value="10485760000" />    
        <!-- 記憶體中的最大值 -->  
        <property name="maxInMemorySize" value="40960" />    
        <!-- 啟用是為了推遲檔案解析,以便捕獲檔案大小異常 -->
        <property name="resolveLazily" value="true"/>
    </bean>   

    <!-- 配置ViewResolver 。可用多個ViewResolver 。使用order屬性排序。   InternalResourceViewResolver 放在最後-->
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1"></property>
        <property name="mediaTypes">
            <map>
                <!-- 告訴視圖解析器,傳回的類型為json格式 -->
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
                <entry key="htm" value="text/htm" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <!-- ModelAndView裡的資料變成JSON -->
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true"></property>
    </bean>

   <!-- 定義跳轉的檔案的前字尾 ,視圖模式配置-->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <!-- 這裡的配置我的了解是自動給後面action的方法return的字元串加上字首和字尾,變成一個 可用的url位址 -->  
        <property name="prefix" value="/WEB-INF/jsp/" />  
        <property name="suffix" value=".jsp" />  
    </bean>  
</beans>  
           

2.2 配置web.xml檔案

配置的spring-mvc的Servlet就是為了完成SpringMVC+MAVEN的整合。

web.xml

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">  
    <display-name>Archetype Created Web Application</display-name>  
    <!-- Spring和mybatis的配置檔案 -->  
   <!-- <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:spring-mybatis.xml</param-value>  
    </context-param> -->
    <!-- 編碼過濾器 -->  
    <filter>  
        <filter-name>encodingFilter</filter-name>  
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
        <async-supported>true</async-supported>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>UTF-8</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>encodingFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    <!-- Spring監聽器 -->  
   <!-- <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener> -->
    <!-- 防止Spring記憶體溢出監聽器 -->  
    <!-- <listener>  
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener> --> 

    <!-- Spring MVC servlet -->  
    <servlet>  
        <servlet-name>SpringMVC</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath:spring-mvc.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
        <async-supported>true</async-supported>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>SpringMVC</servlet-name>  
        <!-- 此處可以可以配置成*.do,對應struts的字尾習慣 -->  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>  
    <welcome-file-list>  
        <welcome-file>/index.jsp</welcome-file>  
    </welcome-file-list>  

</web-app>  
           

2.3 Log4j的配置

為了友善調試,一般都會使用日志來輸出資訊,Log4j是Apache的一個開放源代碼項目,通過使用Log4j,我們可以控制日志資訊輸送的目的地是控制台、檔案、GUI元件,甚至是套接口伺服器、NT的事件記錄器、UNIX Syslog守護程序等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志資訊的級别,我們能夠更加細緻地控制日志的生成過程。

Log4j的配置很簡單,而且也是通用的,下面給出一個基本的配置,換到其他項目中也無需做多大的調整,如果想做調整或者想了解Log4j的各種配置,參看我轉載的一篇博文,很詳細:http://blog.csdn.net/zhshulin/article/details/37937365

下面給出配置檔案目錄:

應用架構@SSM架構原理,作用及使用方法

log4j.properties

log4j.rootLogger=INFO,Console,File  
#定義日志輸出目的地為控制台  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.Target=System.out  
#可以靈活地指定日志輸出格式,下面一行是指定具體的格式  
log4j.appender.Console.layout = org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=[%c] - %m%n  

#檔案大小到達指定尺寸的時候産生一個新的檔案  
log4j.appender.File = org.apache.log4j.RollingFileAppender  
#指定輸出目錄  
log4j.appender.File.File = logs/ssm.log  
#定義檔案最大大小  
log4j.appender.File.MaxFileSize = 10MB  
# 輸出是以日志,如果換成DEBUG表示輸出DEBUG以上級别日志  
log4j.appender.File.Threshold = ALL  
log4j.appender.File.layout = org.apache.log4j.PatternLayout  
log4j.appender.File.layout.ConversionPattern =[%p] [%d{yyyy-MM-dd HH\:mm\:ss}][%c]%m%n  
           

2.4 使用Jetty測試

應用架構@SSM架構原理,作用及使用方法

實體類 User.java

package com.moyue.model;

public class User {
    private Integer id;

    private String userName;

    private String password;

    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName == null ? null : userName.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", userName=" + userName + ", password="
                + password + ", age=" + age + "]";
    }
    
    
}
           

UserController.java

package com.moyue.controller;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;  
import org.springframework.ui.Model;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RequestMethod;
import com.moyue.model.User;
  
  
@Controller  
@RequestMapping("/user")  
// /user/**
public class UserController {  
    private static Logger log=LoggerFactory.getLogger(UserController.class);
      
    
    // /user/test?id=1
    @RequestMapping(value="/test",method=RequestMethod.GET)  
    public String test(HttpServletRequest request,Model model){  
        int userId = Integer.parseInt(request.getParameter("id"));  
        System.out.println("userId:"+userId);
        User user=null;
        if (userId==1) {
             user = new User();  
             user.setAge(11);
             user.setId(1);
             user.setPassword("123");
             user.setUserName("moyue");
        }
       
        log.debug(user.toString());
        model.addAttribute("user", user);  
        return "index";  
    }  
}  
           
應用架構@SSM架構原理,作用及使用方法
應用架構@SSM架構原理,作用及使用方法

在浏覽器中輸入:http://localhost/user/test?id=1

應用架構@SSM架構原理,作用及使用方法

到此 SpringMVC+Maven 整合完畢

3 Spring與MyBatis的整合

取消 2.2 web.xml中注釋的代碼

3.1 建立JDBC屬性檔案

jdbc.properties(檔案編碼修改為utf-8)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/maven
username=root
password=root
#定義初始連接配接數  
initialSize=0 #定義最大連接配接數  
maxActive=20 #定義最大空閑  
maxIdle=20 #定義最小空閑  
minIdle=1 #定義最長等待時間  
maxWait=60000  
           

此時的目錄結構為

應用架構@SSM架構原理,作用及使用方法

3.2 建立spring-mybatis.xml配置檔案

這個檔案就是用來完成spring和mybatis的整合的。這裡面也沒多少行配置,主要的就是自動掃描,自動注入,配置資料庫。注釋也很詳細,大家看看就明白了。

spring-mybatis.xml

<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
    <!-- 自動掃描 -->  
    <context:component-scan base-package="com.moyue" />  

    <!-- 引入配置檔案 -->  
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
        <property name="location" value="classpath:jdbc.properties" />  
    </bean>  

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
        <property name="driverClassName" value="${driver}" />  
        <property name="url" value="${url}" />  
        <property name="username" value="${username}" />  
        <property name="password" value="${password}" />  
        <!-- 初始化連接配接大小 -->  
        <property name="initialSize" value="${initialSize}"></property>  
        <!-- 連接配接池最大數量 -->  
        <property name="maxActive" value="${maxActive}"></property>  
        <!-- 連接配接池最大空閑 -->  
        <property name="maxIdle" value="${maxIdle}"></property>  
        <!-- 連接配接池最小空閑 -->  
        <property name="minIdle" value="${minIdle}"></property>  
        <!-- 擷取連接配接最大等待時間 -->  
        <property name="maxWait" value="${maxWait}"></property>  
    </bean>  

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射檔案 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自動掃描mapping.xml檔案 -->  
        <property name="mapperLocations" value="classpath:com/moyue/mapping/*.xml"></property>  
    </bean>  

    <!-- DAO接口所在包名,Spring會自動查找其下的類 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.moyue.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>  

    <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  

</beans>  

           

3.3 JUnit測試

經過以上步驟,我們已經完成了Spring和mybatis的整合,這樣我們就可以編寫一段測試代碼來試試是否成功了。

1 建立測試用表

既然我們需要測試,那麼我們就需要建立在資料庫中建立一個測試表,這個表建的很簡單,SQL語句為:

-- -- -- 
-- Table structure for `user_t` 
-- ------
DROP TABLE IF EXISTS `user_t`; CREATE TABLE `user_t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(40) NOT NULL,
  `password` varchar(255) NOT NULL,
  `age` int(4) NOT NULL, PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 

-- ---------------------------- 
-- Records of user_t -- 
----------------------------

INSERT INTO `user_t` VALUES (\'1\', \'測試\', \'345\', \'24\'); INSERT INTO `user_t` VALUES (\'2\', \'moyue\', \'123\', \'10\');
           

利用MyBatis Generator自動建立代碼

參考博文:http://blog.csdn.net/zhshulin/article/details/23912615

這個可根據表自動建立實體類、MyBatis映射檔案以及DAO接口,當然,我習慣将生成的接口名改為IUserDao,而不是直接用它生成的UserMapper。如果不想麻煩就可以不改。完成後将檔案複制到工程中。如圖:

應用架構@SSM架構原理,作用及使用方法

2 建立Service接口和實作類

應用架構@SSM架構原理,作用及使用方法

下面給出具體的内容:

IUserService.java

package com.moyue.service;  

import com.moyue.model.User;
  
  
public interface IUserService {  
    public User getUserById(int userId);  
}  
UserServiceImpl.java

package com.moyue.service.impl;
import javax.annotation.Resource;  

import org.springframework.stereotype.Service;  
import com.moyue.dao.IUserDao;
import com.moyue.model.User;
import com.moyue.service.IUserService;
  
  
@Service("userService")  
public class UserServiceImpl implements IUserService {  
    @Resource  
    private IUserDao userDao;  
    
    public User getUserById(int userId) {  
        // TODO Auto-generated method stub  
        return this.userDao.selectByPrimaryKey(userId);  
    }  
  
}  
           

3 建立測試類

測試類在src/test/java中建立,下面測試類中注釋掉的部分是不使用Spring時,一般情況下的一種測試方法;如果使用了Spring那麼就可以使用注解的方式來引入配置檔案和類,然後再将service接口對象注入,就可以進行測試了。

如果測試成功,表示Spring和Mybatis已經整合成功了。輸出資訊使用的是Log4j列印到控制台。

package com.moyue.testmybatis;

import javax.annotation.Resource;  

import org.apache.log4j.Logger;  
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;  
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
import com.alibaba.fastjson.JSON;  
import com.moyue.model.User;
import com.moyue.service.IUserService;
  
@RunWith(SpringJUnit4ClassRunner.class)     //表示繼承了SpringJUnit4ClassRunner類  
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})  
  
public class TestMyBatis {  
    private static Logger logger = Logger.getLogger(TestMyBatis.class);  
//  private ApplicationContext ac = null;  
    @Resource  
    private IUserService userService = null;  
  
//  @Before  
//  public void before() {  
//      ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
//      userService = (IUserService) ac.getBean("userService");  
//  }  
  
    @Test  
    public void test1() {  
        User user = userService.getUserById(1);  
        // System.out.println(user.getUserName());  
        // logger.info("值:"+user.getUserName());  
        logger.info(JSON.toJSONString(user));  
    }  
}  
           

測試結果

應用架構@SSM架構原理,作用及使用方法

4 建立UserController類

UserController.java 控制器

package com.moyue.testmybatis;

import javax.annotation.Resource;  

import org.apache.log4j.Logger;  
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;  
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
import com.alibaba.fastjson.JSON;  
import com.moyue.model.User;
import com.moyue.service.IUserService;
  
@RunWith(SpringJUnit4ClassRunner.class)     //表示繼承了SpringJUnit4ClassRunner類  
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"})  
  
public class TestMyBatis {  
    private static Logger logger = Logger.getLogger(TestMyBatis.class);  
//  private ApplicationContext ac = null;  
    @Resource  
    private IUserService userService = null;  
  
//  @Before  
//  public void before() {  
//      ac = new ClassPathXmlApplicationContext("applicationContext.xml");  
//      userService = (IUserService) ac.getBean("userService");  
//  }  
  
    @Test  
    public void test1() {  
        User user = userService.getUserById(1);  
        // System.out.println(user.getUserName());  
        // logger.info("值:"+user.getUserName());  
        logger.info(JSON.toJSONString(user));  
    }  
}  
           

5 建立jsp頁面

file.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
    <h1>上傳檔案</h1>
    <form method="post" action="/user/doUpload" enctype="multipart/form-data">
        <input type="file" name="file"/>
        <input type="submit" value="上傳檔案"/>

    </form>
</body>
</html>

index.jsp

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
           

showUser.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <title>測試</title>  
  </head>  

  <body> ${user.userName} </body>  
</html>
           

至此,完成Spring+SpingMVC+mybatis這三大架構整合完成。

6 部署項目

輸入位址:http://localhost/user/jsontype/2

應用架構@SSM架構原理,作用及使用方法