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 指定的視圖
- 視圖負責將結果顯示到客戶端
上面補充:
-
攔截器:攔截器主要是在 SpringMVC 的 controller 處理請求之前,對請求做一些處理,攔截器攔截的是 Controller,攔截器分為:HandlerInterceptro(springmvc 的)和 WebRequestInterceptor(spring 的),同時里面一共有三個方法,可以實現部分,主要是攔截位置不同,整體的指向順序為: preHandle ->進入控制器(controller)-> postHandler -> JSP -> afterCompletion;
-
配置文件
- web.xml:在
中要配置前端控制器,springmvc 的配置文件位置、自啟動、攔截器以及編碼過濾器; - springmvc.xml :配置掃描包,即項目中所有 controller 位置,配置注解驅動(一般使用注解),配置不要攔截靜態資源、自定義視圖解析器(就是前后綴,可以和 controller 的返回值相連接,構成完整的頁面路徑);
- controller 中代碼示例:
- web.xml:在
@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");
- 第三步:這樣我們就可以調用業務層(接口實現)的方法。
具體如下:
Java反射博大精深,我也不很懂,具體請查看Java基礎之—反射
那么bean中的東西到底是怎么注入進去的?簡單來講,就是在實例化一個bean時,實際上就實例化了類,它通過反射調用類中set方法將事先保存在HashMap中的類屬性注入到類中。這樣就回到了我們Java最原始的地方,對象.方法,對象.屬性
(二)Spring的原理
-
什么是spring?
-
spring是一個容器框架,它可以接管web層,業務層,dao層,持久層的各個組件,並且可以配置各種bean, 並可以維護bean與bean的關系,當我們需要使用某個bean的時候,我們可以直接getBean(id),使用即可
-
Spring目的:就是讓對象與對象(模塊與模塊)之間的關系沒有通過代碼來關聯,都是通過配置類說明管理的(Spring根據這些配置 內部通過反射去動態的組裝對象) ,Spring是一個容器,凡是在容器里的對象才會有Spring所提供的這些服務和功能。
-
層次框架圖:
說明:
-
web層: struts充當web層,接管jsp,action,表單,主要體現出mvc的數據輸入,數據的處理,數據的顯示分離
- model層: model層在概念上可以理解為包含了業務層,dao層,持久層,需要注意的是,一個項目中,不一定每一個層次都有
- 持久層:體現oop,主要解決關系模型和對象模型之間的阻抗
(三)Spring的核心技術
-
IOC
-
ioc(inverse of control)控制反轉: 所謂反轉就是把創建對象(bean)和維護對象(bean)之間的關系的權利從程序轉移到spring的容器(spring-config.xml)
說明:
<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框架
框架執行流程(面試必問)- 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框架。
-
mvc
- mvc在b/s系統 下的應用:
- 前端控制器DispatcherServlet(不需要程序員開發)
- 作用接收請求,響應結果,相當於轉發器,中央處理器。有了DispatcherServlet減少了其它組件之間的耦合度。
- 處理器映射器HandlerMapping(不需要程序員開發)
- 作用:根據請求的url查找Handler
- 處理器適配器HandlerAdapter
- 作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
- 處理器Handler (需要程序員開發)
- 注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器才可以去正確執行Handler
- 視圖解析器View resolver(不需要程序員開發)
- 作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
- 視圖View (需要程序員開發)
- View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf…)
- mvc在b/s系統 下的應用:
-
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運行流程圖:
第一步:配置文件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、每張表重要的字段設置
- 非空字段、外鍵字段
- 2、每張表重要的字段設置
-
3、數據庫級別表與表之間的關系
- 外鍵關系
-
4、表與表之間的業務關系
- 在分析表與表之間的業務關系時一定要建立 在某個業務意義基礎上去分析。\color{red}{在某個業務意義基礎上去分析。}在某個業務意義基礎上去分析。
5 框架整合示例
下面主要介紹三大框架的整合,至於環境的搭建以及項目的創建,參看上面的博文。這次整合我分了2個配置文件,分別是spring-mybatis.xml,包含spring和mybatis的配置文件,還有個是spring-mvc的配置文件,此外有2個資源文件:jdbc.propertis和log4j.properties。完整目錄結構如下:
使用框架的版本:
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
下面給出配置文件目錄:
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測試
實體類 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";
}
}
在瀏覽器中輸入:http://localhost/user/test?id=1
到此 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
此時的目錄結構為
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。如果不想麻煩就可以不改。完成后將文件復制到工程中。如圖:
2 建立Service接口和實現類
下面給出具體的內容:
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));
}
}
測試結果
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