JavaSSM框架精選50道面試題
1.什么是MVC框架?傳統MVC框架存在的問題是什么?
MVC框架是為了解決傳統MVC模式(Jsp + Servlet + JavaBean)的一些問題而出現的框架。
傳統MVC模式存在問題:
1.所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大,並且不能實現模塊化管理。
2.Servlet的主要功能就是接受參數、調用邏輯、跳轉頁面,比如像其他字符編碼、文件上傳等功能也要寫在Servlet中,不能讓Servlet主要功能而需要做處理一下特例。
3、接受參數比較麻煩(String name = request.getParameter(“name”),User user=new User user.setName(name)),不能通過model接收,只能單個接收,接收完成后轉換封裝model.
4、跳轉頁面方式比較單一(forword,redirect),並且當我的頁面名稱發生改變時需要修改Servlet源代碼.
2簡單介紹下你對springMVC特點的理解?
Spring MVC Framework有這樣一些特點:
1.它是基於組件技術的.全部的應用對象,無論控制器和視圖,還是業務對象之類的都是java組件.並且和Spring提供的其他基礎結構緊密集成.
2.不依賴於Servlet API(目標雖是如此,但是在實現的時候確實是依賴於S.ervlet的)
3.可以任意使用各種視圖技術,而不僅僅局限於JSP
4.支持各種請求資源的映射策略
5.它應是易於擴展的
3.簡單的談一下SpringMVC的工作流程?★★★★★
流程
1、用戶發送請求至前端控制器DispatcherServlet
2、DispatcherServlet收到請求調用HandlerMapping處理器映射器。
3、處理器映射器找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生成)一並返回給DispatcherServlet。
4、DispatcherServlet調用HandlerAdapter處理器適配器
5、HandlerAdapter經過適配調用具體的處理器(Controller,也叫后端控制器)。
6、Controller執行完成返回ModelAndView
7、HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet
8、DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器
9、ViewReslover解析后返回具體View
10、DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
11、DispatcherServlet響應用戶
4.SpringMVC與Struts2的主要區別?
目前企業中使用SpringMvc的比例已經遠遠超過Struts2,那么兩者到底有什么區別,是很多初學者比較關注的問題,下面我們就來對SpringMvc和Struts2進行各方面的比較:
- 核心控制器(前端控制器、預處理控制器):對於使用過mvc框架的人來說這個詞應該不會陌生,核心控制器的主要用途是處理所有的請求,然后對那些特殊的請求 (控制器)統一的進行處理(字符編碼、文件上傳、參數接受、異常處理等等),spring mvc核心控制器是Servlet,而Struts2是Filter。
2.控制器實例:Spring Mvc會比Struts快一些(理論上)。Spring Mvc是基於方法設計,而Sturts是基於對象,每次發一次請求都會實例一個action,每個action都會被注入 屬性,而Spring更像Servlet一樣,只有一個實例,每次請求執行對應的方法即可(注意:由於是單例實例,所以應當避免全局變量的修改,這樣會產生線程安全問題)。
3. 管理方式:大部分的公司的核心架構中,就會使用到spring,而spring mvc又是spring中的一個模塊,所以spring對於spring mvc的控制器管理更加簡單方便,而且提供了全 注解方式進行管理,各種功能的注解都比較全面,使用簡單,而struts2需要采用XML很多的配置參數來管理(雖然也可以采用注解,但是幾乎沒有公司那 樣使用)。
4.參數傳遞:Struts2中自身提供多種參數接受,其實都是通過(ValueStack)進行傳遞和賦值,而SpringMvc是通過方法的參數進行接收。
5.學習難度:Struts更加很多新的技術點,比如攔截器、值棧及OGNL表達式,學習成本較高,springmvc 比較簡單,很較少的時間都能上手。
6.intercepter 的實現機制:struts有以自己的interceptor機制,spring mvc用的是獨立的AOP方式。這樣導致struts的配置文件量還是比spring mvc大,雖然struts的配置能繼承,所以我覺得論使用上來講,spring mvc使用更加簡潔,開發效率Spring MVC確實比struts2高。spring mvc是方法級別的攔截,一個方法對應一個request上下文,而方法同時又跟一個url對應,所以說從架構本身上spring3 mvc就容易實現restful url。struts2是類級別的攔截,一個類對應一個request上下文;實現restful url要費勁,因為struts2 action的一個方法可以對應一個url;而其類屬性卻被所有方法共享,這也就無法用注解或其他方式標識其所屬方法了。spring3 mvc的方法之間基本上獨立的,獨享request response數據,請求數據通過參數獲取,處理結果通過ModelMap交回給框架方法之間不共享變量,而struts2搞的就比較亂,雖然方法之間 也是獨立的,但其所有Action變量是共享的,這不會影響程序運行,卻給我們編碼,讀程序時帶來麻煩。
spring mvc處理ajax請求,直接通過返回數據,方法中使用注解@ResponseBody,spring mvc自動幫我們對象轉換為JSON數據。而struts2是通過插件的方式進行處理
在SpringMVC流行起來之前,Struts2在MVC框架中占核心地位,隨着SpringMVC的出現,SpringMVC慢慢的取代struts2,但是很多企業都是原來搭建的框架,使用Struts2較多。
5.如何解決POST請求中文亂碼問題,GET的又如何處理呢?
在web.xml中加入:
.
. CharacterEncodingFilter
. org.springframework.web.filter.CharacterEncodingFilter
.
. encoding
. utf-8
.
.
.
. CharacterEncodingFilter
. /*
.
以上可以解決post請求亂碼問題。
對於get請求中文參數出現亂碼解決方法有兩個:
修改tomcat配置文件添加編碼與工程編碼一致,如下:
.
另外一種方法對參數進行重新編碼:
. String userName = new String(request.getParamter(“userName”).getBytes(“ISO8859-1”),“utf-8”)
ISO8859-1是tomcat默認編碼,需要將tomcat編碼后的內容按utf-8編碼
6.說出SpringMVC常用的5個注解?如何使用 SpringMVC完成JSON操作?:
常用的 5 個注解
@RequestMapping 、 @PathVariable 、 @RequestParam 、 @RequestBoy 、
@ResponseBody
如何使用 SpringMVC 完成 JSON 操作:
①. 配置 MappingJacksonHttpMessageConverter
②. 使用 @RequestBody 注解或 ResponseEntity 作為返回值
7. Spring 支持的事務管理類型有哪些?你在項目中使用哪種方式?怎么理解全局事務和局部事務?
Spring 支持編程式事務管理和聲明式事務管理。許多 Spring 框架的用戶選擇聲明式事務管理,因為這種方式和應用程序的關聯較少,因此更加符合輕量級容器的概念。聲明式事務管理要優於編程式事務管理,盡管在靈活性方面它弱於編程式事務管理,因為編程式事務允許你通過代碼控制業務。聲明式事務又分為兩種: a、基於XML的聲明式事務 b、基於注解的聲明式事務
事務分為全局事務和局部事務。全局事務由應用服務器管理,需要底層服務器 JTA 支持(如 WebLogic、 WildFly等)。局部事務和底層采用的持久化方案有關,例如使用 JDBC 進行持久化時,需要使用 Connetion 對象來操作事務;而采用 Hibernate 進行持久化時,需要使用 Session 對象來操作事務
8.Spring 提供的事務管理器都有哪些?他們共同實現的父接口是什么?Spring 的事務管理機制體現了什么設計模式,請簡單說說
Spring 提供了如下所示的事務管理器。
這些事務的父接口都是 PlatformTransactionManager。 Spring 的事務管理機制是一種典型的策略模式,PlatformTransactionManager 代表事務管理接口,該接口定義了三個方法,該接口並不知道底層如何管理事務,但是它的實現類必須提供 getTransaction()方法(開啟事務)、 commit()方法(提交事務)、 rollback()方法(回滾事務)的多態實現,這樣就可以用不同的實現類代表不同的事務管理策略。使用 JTA 全局事務策略時,需要底層應用服務器支持,而不同的應用服務器所提供的 JTA 全局事務可能存在細節上的差異,因此實際配置全局事務管理器是可能需要使用 JtaTransactionManager 的子類,如: WebLogicJtaTransactionManager( Oracle 的 WebLogic 服務器提供)、 UowJtaTransactionManager( IBM 的 WebSphere 服務器提供)等。
9.Spring為什么要結合使用HandlerMapping以及HandlerAdapter來處理Handler?
符合面向對象中的單一職責原則,代碼架構清晰,便於維護,最重要的是代碼可復用性高。如HandlerAdapter可能會被用於處理多種Handler。
10.簡單介紹下你對mybatis的理解?
1. mybatis配置
2. SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運行環境等信息。
3. mapper.xml文件即sql映射文件,文件中配置了操作數據庫的sql語句。此文件需要在SqlMapConfig.xml中加載。
4. 通過mybatis環境等配置信息構造SqlSessionFactory即會話工廠
5. 由會話工廠創建sqlSession即會話,操作數據庫需要通過sqlSession進行。
6. mybatis底層自定義了Executor執行器接口操作數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。
7. Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id即是Mapped statement的id。
8. Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。
9. Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql后將輸出結果映射至java對象中,輸出結果映射過程相當於jdbc編程中對結果的解析處理過程。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
11.SpringMvc的控制器是不是單例模式,如果是,有什么問題,怎么解決?
是單例模式,所以在多線程訪問的時候有線程安全問題,不要用同步,會影響性能的,解決方案是在控制器里面不能寫字段。
12.SpingMvc中的控制器的注解一般用哪個,有沒有別的注解可以替代?
一般用@Conntroller注解,表示是表現層,不能用用別的注解代替
13. (1)@RequestMapping注解用在類上面有什么作用?(2)怎么樣把某個請求映射到特定的方法上面?
(1)@RequestMapping注解用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
(2)如何把某個請求映射到特定的方法上面方案:直接在方法上面加上注解@RequestMapping,並且在這個注解里面寫上要攔截的路徑
14(1)如果在攔截請求中,我想攔截get方式提交的方法,怎么配置?
(2) 如果在攔截請求中,我想攔截提交參數中包含"type=test"字符串,怎么配置?
可以在@RequestMapping注解里面加上method=RequestMethod.GET
可以在@RequestMapping注解里面加上params=“type=test”
15(1)我想在攔截的方法里面得到從前台傳入的參數,怎么得到?
(2)如果前台有很多個參數傳入,並且這些參數都是一個對象的,那么怎么樣快速得到這個對象?
直接在形參里面聲明這個參數就可以,但必須名字和傳過來的參數一樣
直接在方法中聲明這個對象,SpringMvc就自動會把屬性賦值到這個對象里面
16(1) 怎么樣在方法里面得到Request,或者Session?(2)SpringMVC怎么樣設定重定向和轉發的?
直接在方法的形參中聲明request,SpringMvc就自動把request對象傳入
在返回值前面加"forward:“就可以讓結果轉發,譬如"forward:user.do?name=method4” 在返回值前面加"redirect:“就可以讓返回值重定向,譬如"redirect:http://www.baidu.com”
17(1)SpringMvc中函數的返回值都有哪些?(2) SpringMvc怎么處理返回值的?
(1)返回值可以有很多類型,有String, ModelAndView,當一般用String比較好
(2) SpringMvc根據配置文件中InternalResourceViewResolver的前綴和后綴,用前綴+返回值+后綴組成完整的返回值
18(1)SpringMvc用什么對象從后台向前台傳遞數據的?(2)SpringMvc中有個類把視圖和數據都合並的一起的,叫什么?
通過ModelMap對象,可以在這個對象里面用put方法,把對象加到里面,前台就可以通過el表達式拿到
SpringMvc中有個類把視圖和數據都合並的一起的叫ModelAndView
19(1)怎么樣把ModelMap里面的數據放入Session里面?(2)SpringMvc怎么和AJAX相互調用的?
可以在類上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key
通過Jackson框架就可以把Java里面的對象直接轉化成Js可以識別的Json對象
具體步驟如下
1.加入Jackson.jar
2.在配置文件中配置json的映射
3.在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解
MyBatis部分
- 1
20 談一下使用MyBatis(IBatis)的好處是什么?
ibatis把sql語句從Java源程序中獨立出來,放在單獨的XML文件中編寫,給程序的維護帶來了很大便利。
ibatis封裝了底層JDBC API的調用細節,並能自動將結果集轉換成Java Bean對象,大大簡化了Java數據庫編程的重復工作。
因為Ibatis需要程序員自己去編寫sql語句,程序員可以結合數據庫自身的特點靈活控制sql語句,
因此能夠實現比hibernate等全自動orm框架更高的查詢效率,能夠完成復雜查詢。
21講下對MyBatis的緩存的理解?
MyBatis的緩存分為一級緩存和二級緩存,一級緩存放在session里面,默認就有,二級緩存放在它的命名空間里,默認是打開的,使用二級緩存屬性類需要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置
22(1)IBatis和MyBatis在核心處理類分別叫什么?(2)IBatis和MyBatis在細節上的不同有哪些?【擴展】
(1)IBatis里面的核心處理類交SqlMapClient,MyBatis里面的核心處理類叫做SqlSession
(2)細節上的不同:在sql里面變量命名有原來的#變量# 變成了#{變量} 原來的變量變量變量變成了${變量},
原來在sql節點里面的class都換名字交type
原來的queryForObject queryForList 變成了selectOne selectList
原來的別名設置在映射文件里面放在了核心配置文件里
23 MyBatis里面的動態Sql是怎么設定的?用什么語法?
MyBatis里面的動態Sql一般是通過if節點來實現,通過OGNL語法來實現,但是如果要寫的完整,必須配合where,trim節點,where節點是判斷包含節點有內容就插入where,否則不插入,trim節點是用來判斷如果動態語句是以and 或or開始,那么會自動把這個and或者or取掉
24 MyBatis實現一對多有幾種方式?怎么操作的?
有聯合查詢和嵌套查詢,
聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap里面配置collection節點配置一對多的類就可以完成;
嵌套查詢是先查一個表,根據這個表里面的結果的外鍵id,去再另外一個表里面查詢數據,也是通過配置collection,但另外一個表的查詢通過select節點配置
可以參考以下代碼理解:
25 MyBatis實現一對一有幾種方式?具體怎么操作的?
有聯合查詢和嵌套查詢,
聯合查詢是幾個表聯合查詢,只查詢一次,通過在resultMap里面配置association節點配置一對一的類就可以完成;
嵌套查詢是先查一個表,根據這個表里面的結果的外鍵id,去再另外一個表里面查詢數據,也是通過association配置,但另外一個表的查詢通過select屬性配置
26什么是MyBatis的接口綁定?有什么好處?
接口映射就是在IBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置.
27(1)接口綁定有幾種實現方式,分別是怎么實現的? (2)什么情況下用注解綁定,什么情況下用xml綁定
(1)接口綁定有兩種實現方式,一種是通過注解綁定,就是在接口的方法上面加上@Select @Update等注解里面包含Sql語句來綁定,另外一種就是通過xml里面寫SQL來綁定,在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名.
(2)當Sql語句比較簡單時候,用注解綁定,當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多
28說一下orm與jdbc的區別?
jdbc只是一個java操作數據庫的規范接口而已
orm不過是一種思想,對象關系映射。
ORM:是對象關系模型,如hibernate,讓你以面向對象的方式去編程。封裝了JDBC.
JDBC:是從底層訪問數據庫服務器。一般銀行,金融行業為了安全起見,直接用JDBC訪問
29傳統mvc模式存在什么問題?或者說為何要使用框架?
傳統MVC模式存在問題
(1)所有的Servlet和Servlet映射都要配置在web.xml中,如果項目太大,web.xml就太龐大,並且不能實現模塊化管理。
(2)Servlet的主要功能就是接受參數、調用邏輯、跳轉頁面,比如像其他字符編碼、文件上傳等功能也要寫在Servlet中,不能讓Servlet主要功能而需要做處理一下特例。
(3)接受參數比較麻煩(String name = request.getParameter(“name”),User user=new User user.setName(name)),不能通過model接收,只能單個接收,接收完成后轉換封裝model.
(4)跳轉頁面方式比較單一(forword,redirect),並且當我的頁面名稱發生改變時需要修改Servlet源代碼.
是為了解決傳統MVC模式(Jsp + Servlet + JavaBean)的一些問題,才出現了后來的MVC框架。
30 mybatis與Hibernate有什么不同?
相同點:都是java中orm框架、屏蔽jdbc api的底層訪問細節,使用我們不用與jdbc api打交道,就可以完成對數據庫的持久化操作。jdbc api編程流程固定,還將sql語句與java代碼混雜在了一起,經常需要拼湊sql語句,細節很繁瑣。
ibatis的好處:屏蔽jdbc api的底層訪問細節;將sql語句與java代碼進行分離;提供了將結果集自動封裝稱為實體對象和對象的集合的功能.queryForList返回對象集合,用queryForObject返回單個對象;提供了自動將實體對象的屬性傳遞給sql語句的參數。
Hibername的好處:Hibernate是一個全自動的orm映射工具,它可以自動生成sql語句,並執行並返回java結果。
不同點:
1、hibernate要比ibatis功能強大很多。因為hibernate自動生成sql語句。
2、ibatis需要我們自己在xml配置文件中寫sql語句,hibernate我們無法直接控制該語句,我們就無法去寫特定的高效率的sql。對於一些不太復雜的sql查詢,hibernate可以很好幫我們完成,但是,對於特別復雜的查詢,hibernate就很難適應了,這時候用ibatis就是不錯的選擇,因為ibatis還是由我們自己寫sql語句。
ibatis可以出來復雜語句,而hibernate不能。
3、ibatis要比hibernate簡單的多。ibatis是面向sql的,不同考慮對象間一些復雜的映射關系。
31 解釋下MyBatis 中的動態SQL的理解?
對於一些復雜的查詢,我們可能會指定多個查詢條件,但是這些條件可能存在也可能不存在,例如在58同城上面找房子,我們可能會指定面積、樓層和所在位置來查找房源,也可能會指定面積、價格、戶型和所在位置來查找房源,此時就需要根據用戶指定的條件動態生成 SQL 語句。如果不使用持久層框架我們可能需要自己拼裝 SQL 語句,還好 MyBatis 提供了動態 SQL 的功能來解決這個問題。 MyBatis 中用於實現動態 SQL 的元素主要有:
- if
- choose / when / otherwise
- trim
- where
- set
- foreach
其中
If標簽: 多個條件查詢時候用到
Where標簽:可以自動處理第一個and
Foreach:應用場景 在多個ID查詢時 傳遞的是集合或者是數組時候
Foreach的屬性:
Collection: Java對象的屬性名
Open:sql拼接開始的語句
Close: 結束時的SQL語句
Item:查詢SQL中的字段名
Separator:語句拼接時候用什么進行分割
可以參考如下代碼理解:
select * from t_blog where 1 = 1
and title = #{title}
and content = #{content}
and owner = #{owner}
當然也可以像下面這些書寫。
select * from t_blog where 1 = 1
and title = #{title}
and content = #{content}
and owner = “owner1”
再看看下面這個例子。
select * from t_blog where id in
#{item}
32.JDBC編程有哪些不足之處,MyBatis是如何解決這些問題的?
① 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。
解決:在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。
② Sql語句寫在代碼中造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。
解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
③ 向sql語句傳參數麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參數一一對應。
解決: Mybatis自動將java對象映射至sql語句。
④ 對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成pojo對象解析比較方便。
解決:Mybatis自動將sql執行結果映射至java對象。
另外的參考回答
頻繁的創建數據連接,關閉資源,造成性能的下降,使用數據文庫連接池 解決這個問題用數據庫連接池.在SqlMapConfig.xml 配置數據庫連接池 c3p0 DBCP
Jdbc 編程sql 的可維護性不高. Mybatis采用配置文件的方式解決sql可維護的問題
在mapper.xml中配置 ,是sql與代碼分離 可維護行變高
Jdbc 傳入參數比較麻煩. 參數有時候多,參數要和占位符一一對應.
Mybatis 使用statement 的 paremterType 定義輸入的參數類型
對結果解析比較麻煩. Mybatis 使用resultType 自動映射到pojo中解決了jdbc解析結果的麻煩
33.MyBatis編程步驟是什么樣的?
① 創建SqlSessionFactory
② 通過SqlSessionFactory創建SqlSession
③ 通過sqlsession執行數據庫操作
④ 調用session.commit()提交事務
⑤ 調用session.close()關閉會話
34.使用MyBatis的mapper接口調用時有哪些要求?
① Mapper接口方法名和mapper.xml中定義的每個sql的id相同
② Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
③ Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
④ Mapper.xml文件中的namespace即是mapper接口的類路徑。
35.SqlMapConfig.xml中配置有哪些內容?
SqlMapConfig.xml中配置的內容和順序如下:
properties(屬性)
settings(配置)
typeAliases(類型別名)
typeHandlers(類型處理器)
objectFactory(對象工廠)
plugins(插件)
environments(環境集合屬性對象)
environment(環境子屬性對象)
transactionManager(事務管理)
dataSource(數據源)
mappers(映射器)
36.簡單的說一下MyBatis的一級緩存和二級緩存?
Mybatis首先去緩存中查詢結果集,如果沒有則查詢數據庫,如果有則從緩存取出返回結果集就不走數據庫。Mybatis內部存儲緩存使用一個HashMap,key為hashCode+sqlId+Sql語句。value為從查詢出來映射生成的java對象
Mybatis的二級緩存即查詢緩存,它的作用域是一個mapper的namespace,即在同一個namespace中查詢sql可以從緩存中獲取數據。二級緩存是可以跨SqlSession的。
37.Mapper編寫有哪幾種方式?
①接口實現類繼承SqlSessionDaoSupport
使用此種方法需要編寫mapper接口,mapper接口實現類、mapper.xml文件
1、在sqlMapConfig.xml中配置mapper.xml的位置
.
.
.
.
2、定義mapper接口
3、實現類集成SqlSessionDaoSupport
mapper方法中可以this.getSqlSession()進行數據增刪改查。
4、spring 配置
.
.
.
②使用org.mybatis.spring.mapper.MapperFactoryBean
1、在sqlMapConfig.xml中配置mapper.xml的位置
如果mapper.xml和mappre接口的名稱相同且在同一個目錄,這里可以不用配置
.
.
.
.
2、定義mapper接口
注意
1、mapper.xml中的namespace為mapper接口的地址
2、mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致
3、 Spring中定義
.
.
.
.
③使用mapper掃描器
1、mapper.xml文件編寫,
注意:
mapper.xml中的namespace為mapper接口的地址
mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致
如果將mapper.xml和mapper接口的名稱保持一致則不用在sqlMapConfig.xml中進行配置
2、定義mapper接口
注意mapper.xml的文件名和mapper的接口名稱保持一致,且放在同一個目錄
3、配置mapper掃描器
.
.
.
.
4、使用掃描器后從spring容器中獲取mapper的實現對象
掃描器將接口通過代理方法生成實現對象,要spring容器中自動注冊,名稱為mapper 接口的名稱。
38 mybatis中${value}與#{} 的區別是什么?
#{} 表示占位符.可以實現preparedStatement 向占位符中設置值,#{}可以接受簡單類型,pojo屬性值, #{}可以防止sql注入.如果preparedStatement 中傳入簡單類型 #{value} 可以隨意寫但是不可以不寫
valueSQL語句的拼接.可以接收pojo屬性值和簡單數類型,如果preparedStatemet傳入簡單數據類型,{value} SQL 語句的拼接.可以接收pojo屬性值和簡單數類型,如果preparedStatemet 傳入簡單數據類型,valueSQL語句的拼接.可以接收pojo屬性值和簡單數類型,如果preparedStatemet傳入簡單數據類型,{value} 只能是value 不能改變
另外一種參考答案:
#{}是預編譯處理,KaTeX parse error: Expected 'EOF', got '#' at position 21: …串替換。 Mybatis在處理#̲{}時,會將sql中的#{}替…{}時,就是把${}替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
39 JDBC 與數據庫交互的流程是什么?
加載數據庫驅動
獲取數據庫連接
創建statement 對象
設置SQL語句
設置SQL語句參數
使用Sstatement對象執行SQL語句
獲取結果集 解析結果集
關閉資源
40 談談對mybatis中的sqlSession、sqlSessionFactoryBuild和sqlSessionFactory的理解。
sqlSession:封裝了對數據 增刪改查的方法
sqlSession是通過sqlSessionFactory創建的
.sqlSessionFactory是通過sqlSessionFactoryBuild創建的
sqlSessionFactoryBuild 是創建sqlSessionFactory時使用的.一旦創建成功后就不需要sqlSessionFactoryBuild的,因為sqlSession是通過sqlSessionFactory創建的,可以可以當做工具類使用
sqlSessionFactory是一個接口, 類里重載了opensession的不同的方法使用范圍是在整個運行范圍內,一旦創建可以重復使用.可以當做單實例對象來管理
sqlSession是面向用戶的一個操作數據庫的接口 每個線程都應該有自己的sqlSession 並且sqlSession不可以共享. 線程是不安全的,打開一個sqlSession用完之后就要關閉
41 談下對mybatis中Sql片段的理解
使用sql標簽 屬性 id 作為SQL標簽的唯一標識
可以把條件和查詢結果的字段抽取出來
引用的時候 使用include標簽引用
注意:如果引用其它mapper.xml的sql片段,則在引用時需要加上namespace,如下:
<include refid="namespace.sql片段”/>
42 通常一個xml映射文件,都會寫一個Dao接口與之對應,請問這個Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法可以重載嗎?為啥?
Dao接口,就是人們常說的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法內的參數,就是傳遞給sql的參數。Mapper接口是沒有實現類的,當調用接口方法時,接口全限名+方法名拼接字符串作為key值,可唯一定位一個MappedStatement,舉例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace為com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一個、、、標簽,都會被解析為一個MappedStatement對象。
Dao接口里的方法,是不能重載的,因為是全限名+方法名的保存和尋找策略。
Dao接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所代表的sql,然后將sql執行結果返回。
43 mybatis是如何進行分頁的?分頁插件的原理是什么?
Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁,可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。
分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。
44.Mybatis是如何將sql執行結果封裝為目標對象並返回的?都有哪些映射形式?
第一種是使用標簽,逐一定義列名和對象屬性名之間的映射關系。第二種是使用sql列的別名功能,將列別名書寫為對象屬性名,比如T_NAME AS NAME,對象屬性名一般是name,小寫,但是列名不區分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應對象屬性名,你甚至可以寫成T_NAME AS NaMe,Mybatis一樣可以正常工作。
有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值並返回,那些找不到映射關系的屬性,是無法完成賦值的。
45. Xml映射文件中,除了常見的select|insert|update|delete標簽之外,還有哪些標簽?
還有很多其他的標簽,加上動態sql的9個標簽,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中為sql片段標簽,通過標簽引入sql片段,為不支持自增的主鍵生成策略標簽。
46. 簡述Mybatis的插件運行原理,以及如何編寫一個插件
Mybatis僅可以編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種接口的插件,Mybatis使用JDK的動態代理,為需要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這4種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法,當然,只會攔截那些你指定需要攔截的方法。實現Mybatis的Interceptor接口並復寫intercept()方法,然后在給插件編寫注解,指定要攔截哪一個接口的哪些方法即可,記住,還需要在配置文件中配置你編寫的插件。
47. 簡述Mybatis一級、二級緩存
1)一級緩存: 基於 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空。
2)二級緩存與一級緩存其機制相同,默認也是采用 PerpetualCache,HashMap 存儲,不同在於其存儲作用域為 Mapper(Namespace),並且可自定義存儲源,如 Ehcache。要開啟二級緩存,你需要在你的 SQL 映射文件中添加一行:
3)對於緩存數據更新機制,當某一個作用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操作后,默認該作用域下所有 select 中的緩存將被 clear。
48. Mybatis是否支持延遲加載?如果支持,它的實現原理是什么?
Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB創建目標對象的代理對象,當調用目標方法時,進入攔截器方法,比如調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那么就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,然后調用a.setB(b),於是a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。
49. Mybatis映射文件中,如果A標簽通過include引用了B標簽的內容,請問,B標簽能否定義在A標簽的后面,還是說必須定義在A標簽的前面?
雖然Mybatis解析Xml映射文件是按照順序解析的,但是,被引用的B標簽依然可以定義在任何地方,Mybatis都可以正確識別。
原理是,Mybatis解析A標簽,發現A標簽引用了B標簽,但是B標簽尚未解析到,尚不存在,此時,Mybatis會將A標簽標記為未解析狀態,然后繼續解析余下的標簽,包含B標簽,待所有標簽解析完畢,Mybatis會重新解析那些被標記為未解析的標簽,此時再解析A標簽時,B標簽已經存在,A標簽也就可以正常解析完成了。
50. 簡述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關系?
Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內部。在Xml映射文件中,標簽會被解析為ParameterMap對象,其每個子元素會被解析為ParameterMapping對象。標簽會被解析為ResultMap對象,其每個子元素會被解析為ResultMapping對象。每一個、、、標簽均會被解析為MappedStatement對象,標簽內的sql會被解析為BoundSql對象。
