一、Spring篇
1、什么是Spring框架?
Spring是一種輕量級框架,提高開發(fā)人員的開發(fā)效率以及系統的可維護性。
我們一般說的Spring框架就是Spring Framework,它是很多模塊的集合,使用這些模塊可以很方便地協助我們進行開發(fā)。這些模塊是核心容器、數據訪問/集成、Web、AOP(面向切面編程)、工具、消息和測試模塊。比如Core Container中的Core組件是Spring所有組件的核心,Beans組件和Context組件是實現IOC和DI的基礎,AOP組件用來實現面向切面編程。
Spring的6個特征:
核心技術:依賴注入(DI),AOP,事件(Events),資源,i18n,驗證,數據綁定,類型轉換,SpEL。
測試:模擬對象,TestContext框架,Spring MVC測試,WebTestClient。
數據訪問:事務,DAO支持,JDBC,ORM,編組XML。
Web支持:Spring MVC和Spring WebFlux Web框架。
集成:遠程處理,JMS,JCA,JMX,電子郵件,任務,調度,緩存。
語言:Kotlin,Groovy,動態(tài)語言。
2、列舉一些重要的Spring模塊?
Spring Core:核心,可以說Spring其他所有的功能都依賴于該類庫。主要提供IOC和DI功能。
Spring Aspects:該模塊為與AspectJ的集成提供支持。
Spring AOP:提供面向切面的編程實現。
Spring JDBC:Java數據庫連接。
Spring JMS:Java消息服務。
Spring ORM:用于支持Hibernate等ORM工具。
Spring Web:為創(chuàng)建Web應用程序提供支持。
Spring Test:提供了對JUnit和TestNG測試的支持。
3、談談自己對于Spring IOC和AOP的理解
IOC(Inversion Of Controll,控制反轉)是一種設計思想:
在程序中手動創(chuàng)建對象的控制權,交由給Spring框架來管理。IOC在其他語言中也有應用,并非Spring特有。IOC容器實際上就是一個Map(key, value),Map中存放的是各種對象。
將對象之間的相互依賴關系交給IOC容器來管理,并由IOC容器完成對象的注入。這樣可以很大程度上簡化應用的開發(fā),把應用從復雜的依賴關系中解放出來。IOC容器就像是一個工廠一樣,當我們需要創(chuàng)建一個對象的時候,只需要配置好配置文件/注解即可,完全不用考慮對象是如何被創(chuàng)建出來的。在實際項目中一個Service類可能由幾百甚至上千個類作為它的底層,假如我們需要實例化這個Service,可能要每次都搞清楚這個Service所有底層類的構造函數,這可能會把人逼瘋。如果利用IOC的話,你只需要配置好,然后在需要的地方引用就行了,大大增加了項目的可維護性且降低了開發(fā)難度。
4、Spring中的bean的作用域有哪些?
1.singleton:該bean實例為單例
2.prototype:每次請求都會創(chuàng)建一個新的bean實例(多例)。
3.request:每一次HTTP請求都會產生一個新的bean,該bean僅在當前HTTP request內有效。
4.session:每一次HTTP請求都會產生一個新的bean,該bean僅在當前HTTP session內有效。
5.global-session:全局session作用域,僅僅在基于Portlet的Web應用中才有意義,Spring5中已經沒有了。Portlet是能夠生成語義代碼(例如HTML)片段的小型Java Web插件。它們基于Portlet容器,可以像Servlet一樣處理HTTP請求。但是與Servlet不同,每個Portlet都有不同的會話。
5、Spring中的單例bean的線程安全問題了解嗎?
概念用于理解:大部分時候我們并沒有在系統中使用多線程,所以很少有人會關注這個問題。單例bean存在線程問題,主要是因為當多個線程操作同一個對象的時候,對這個對象的非靜態(tài)成員變量的寫操作會存在線程安全問題。
有兩種常見的解決方案(用于回答的點):
1.在bean對象中盡量避免定義可變的成員變量(不太現實)。
2.在類中定義一個ThreadLocal成員變量,將需要的可變成員變量保存在ThreadLocal(線程本地化對象)中(推薦的一種方式)。
ThreadLocal解決多線程變量共享問題(參考博客):
https://segmentfault.com/a/1190000009236777
6、Spring中Bean的生命周期:
1.Bean容器找到配置文件中Spring Bean的定義。
2.Bean容器利用Java Reflection API創(chuàng)建一個Bean的實例。
3.如果涉及到一些屬性值,利用set()方法設置一些屬性值。
4.如果Bean實現了BeanNameAware接口,調用setBeanName()方法,傳入Bean的名字。
5.如果Bean實現了BeanClassLoaderAware接口,調用setBeanClassLoader()方法,傳入ClassLoader對象的實例。
6.如果Bean實現了BeanFactoryAware接口,調用setBeanClassFacotory()方法,傳入ClassLoader對象的實例。
7.與上面的類似,如果實現了其他*Aware接口,就調用相應的方法。
8.如果有和加載這個Bean的Spring容器相關的BeanPostProcessor對象,執(zhí)postProcessBeforeInitialization()方法。
9.如果Bean實現了InitializingBean接口,執(zhí)行afeterPropertiesSet()方法。
10.如果Bean在配置文件中的定義包含init-method屬性,執(zhí)行指定的方法。
11.如果有和加載這個Bean的Spring容器相關的BeanPostProcess對象,執(zhí)行postProcessAfterInitialization()方法。
12.當要銷毀Bean的時候,如果Bean實現了DisposableBean接口,執(zhí)行destroy()方法。
13.當要銷毀Bean的時候,如果Bean在配置文件中的定義包含destroy-method屬性,執(zhí)行指定的方法。
7、Spring框架中用到了哪些設計模式?
1.工廠設計模式:Spring使用工廠模式通過BeanFactory和ApplicationContext創(chuàng)建bean對象。
2.代理設計模式:Spring AOP功能的實現。
3.單例設計模式:Spring中的bean默認都是單例的。
4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template結尾的對數據庫操作的類,它們就使用到了模板模式。
5.包裝器設計模式:我們的項目需要連接多個數據庫,而且不同的客戶在每次訪問中根據需要會去訪問不同的數據庫。這種模式讓我們可以根據客戶的需求能夠動態(tài)切換不同的數據源。
6.觀察者模式:Spring事件驅動模型就是觀察者模式很經典的一個應用。
7.適配器模式:Spring AOP的增強或通知(Advice)使用到了適配器模式、Spring MVC中也是用到了適配器模式適配Controller。
還有很多。。。。。。。
8、@Component和@Bean的區(qū)別是什么
1.作用對象不同。@Component注解作用于類,而@Bean注解作用于方法。
2.@Component注解通常是通過類路徑掃描來自動偵測以及自動裝配到Spring容器中(我們可以使用@ComponentScan注解定義要掃描的路徑)。@Bean注解通常是在標有該注解的方法中定義產生這個bean,告訴Spring這是某個類的實例,當我需要用它的時候還給我。
3.@Bean注解比@Component注解的自定義性更強,而且很多地方只能通過@Bean注解來注冊bean。比如當引用第三方庫的類需要裝配到Spring容器的時候,就只能通過@Bean注解來實現。
1、
@Configuration
public class AppConfig {
@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}
}
2、
<beans>
<bean id="transferService" class="com.kk.TransferServiceImpl"/>
</beans>
3、
@Bean
public OneService getService(status) {
case (status) {
when 1:
return new serviceImpl1();
when 2:
return new serviceImpl2();
when 3:
return new serviceImpl3();
}
}
9、將一個類聲明為Spring的bean的注解有哪些?
1、聲明bean的注解:
@Component 組件,沒有明確的角色
@Service 在業(yè)務邏輯層使用(service層)
@Repository 在數據訪問層使用(dao層)
@Controller 在展現層使用,控制器的聲明
2、注入bean的注解:
@Autowired:由Spring提供
@Inject:由JSR-330提供
@Resource:由JSR-250提供
*擴:JSR 是 java 規(guī)范標準
10、Spring事務管理的方式有幾種?
1.編程式事務:在代碼中硬編碼(不推薦使用)。
2.聲明式事務:在配置文件中配置(推薦使用),分為基于XML的聲明式事務和基于注解的聲明式事務。
11、Spring事務中的隔離級別有哪幾種?
在TransactionDefinition接口中定義了五個表示隔離級別的常量:
ISOLATION_DEFAULT:使用后端數據庫默認的隔離級別,Mysql默認采用的REPEATABLE_READ隔離級別;Oracle默認采用的READ_COMMITTED隔離級別。
ISOLATION_READ_UNCOMMITTED:最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀。
ISOLATION_READ_COMMITTED:允許讀取并發(fā)事務已經提交的數據,可以阻止臟讀,但是幻讀或不可重復讀仍有可能發(fā)生
ISOLATION_REPEATABLE_READ:對同一字段的多次讀取結果都是一致的,除非數據是被本身事務自己所修改,可以阻止臟讀和不可重復讀,但幻讀仍有可能發(fā)生。
ISOLATION_SERIALIZABLE:最高的隔離級別,完全服從ACID的隔離級別。所有的事務依次逐個執(zhí)行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。
12、Spring事務中有哪幾種事務傳播行為?
在TransactionDefinition接口中定義了八個表示事務傳播行為的常量。
1、支持當前事務的情況:
PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則創(chuàng)建一個新的事務。
PROPAGATION_SUPPORTS: 如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續(xù)運行。
PROPAGATION_MANDATORY: 如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。(mandatory:強制性)。
2、不支持當前事務的情況:
PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個新的事務,如果當前存在事務,則把當前事務掛起。
PROPAGATION_NOT_SUPPORTED: 以非事務方式運行,如果當前存在事務,則把當前事務掛起。
PROPAGATION_NEVER: 以非事務方式運行,如果當前存在事務,則拋出異常。
3、其他情況:
PROPAGATION_NESTED: 如果當前存在事務,則創(chuàng)建一個事務作為當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價于PROPAGATION_REQUIRED。
二、SpringMVC篇
1、什么是Spring MVC ?簡單介紹下你對springMVC的理解?
Spring MVC是一個基于Java的實現了MVC設計模式的請求驅動類型的輕量級Web框架,通過把Model,View,Controller分離,將web層進行職責解耦,把復雜的web應用分成邏輯清晰的幾部分,簡化開發(fā),減少出錯,方便組內開發(fā)人員之間的配合。
2、Spring MVC的工作原理了解嘛?

3、Springmvc的優(yōu)點:
(1)可以支持各種視圖技術,而不僅僅局限于JSP;
(2)與Spring框架集成(如IoC容器、AOP等);
(3)清晰的角色分配:前端控制器(dispatcherServlet) , 請求到處理器映射(handlerMapping), 處理器適配器(HandlerAdapter), 視圖解析器(ViewResolver)。
(4) 支持各種請求資源的映射策略。
4、Spring MVC的主要組件?
(1)前端控制器 DispatcherServlet(不需要程序員開發(fā))
作用:接收請求、響應結果,相當于轉發(fā)器,有了DispatcherServlet 就減少了其它組件之間的耦合度。
(2)處理器映射器HandlerMapping(不需要程序員開發(fā))
作用:根據請求的URL來查找Handler
(3)處理器適配器HandlerAdapter
注意:在編寫Handler的時候要按照HandlerAdapter要求的規(guī)則去編寫,這樣適配器HandlerAdapter才可以正確的去執(zhí)行Handler。
(4)處理器Handler(需要程序員開發(fā))
(5)視圖解析器 ViewResolver(不需要程序員開發(fā))
作用:進行視圖的解析,根據視圖邏輯名解析成真正的視圖(view)
(6)視圖View(需要程序員開發(fā)jsp)
View是一個接口, 它的實現類支持不同的視圖類型(jsp,freemarker,pdf等等)
5、springMVC和struts2的區(qū)別有哪些?
(1)springmvc的入口是一個servlet即前端控制器(DispatchServlet),而struts2入口是一個filter過慮器(StrutsPrepareAndExecuteFilter)。
(2)springmvc是基于方法開發(fā)(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基于類開發(fā),傳遞參數是通過類的屬性,只能設計為多例。
(3)Struts采用值棧存儲請求和響應的數據,通過OGNL存取數據,springmvc通過參數解析器是將request請求內容解析,并給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數據通過reques域傳輸到頁面。Jsp視圖解析器默認使用jstl。
6、SpringMVC怎么樣設定重定向和轉發(fā)的?
(1)轉發(fā):在返回值前面加"forward:",譬如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
7、SpringMvc怎么和AJAX相互調用的?
通過Jackson框架就可以把Java里面的對象直接轉化成Js可以識別的Json對象。具體步驟如下 :
(1)加入Jackson.jar
(2)在配置文件中配置json的映射
(3)在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。
8、如何解決POST請求中文亂碼問題,GET的又如何處理呢?
(1)解決post請求亂碼問題:
在web.xml中配置一個CharacterEncodingFilter過濾器,設置成utf-8;
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2)get請求中文參數出現亂碼解決方法有兩個:
①修改tomcat配置文件添加編碼與工程編碼一致,如下:
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
②另外一種方法對參數進行重新編碼:
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默認編碼,需要將tomcat編碼后的內容按utf-8編碼。
9、Spring MVC的異常處理 ?
統一異常處理:
Spring MVC處理異常有3種方式:
(1)使用Spring MVC提供的簡單異常處理器SimpleMappingExceptionResolver;
(2)實現Spring的異常處理接口HandlerExceptionResolver 自定義自己的異常處理器;
(3)使用@ExceptionHandler注解實現異常處理;
統一異常處理的博客:
https://blog.csdn.net/ctwy291314/article/details/81983103
10、SpringMVC的控制器是不是單例模式,如果是,有什么問題,怎么解決?
是單例模式,所以在多線程訪問的時候有線程安全問題,不要用同步,會影響性能的,解決方案是在控制器里面不能寫成員變量。(此題目類似于上面Spring 中 第5題 有兩種解決方案)
11、 SpringMVC常用的注解有哪些?
@RequestMapping:用于處理請求 url 映射的注解,可用于類或方法上。用于類上,則表示類中的所有響應請求的方法都是以該地址作為父路徑。
@RequestBody:注解實現接收http請求的json數據,將json轉換為java對象。
@ResponseBody:注解實現將conreoller方法返回對象轉化為json對象響應給客戶。
12、SpingMvc中的控制器的注解一般用那個,有沒有別的注解可以替代?
一般用@Controller注解,也可以使用@RestController,@RestController注解相當于@ResponseBody + @Controller,表示是表現層,除此之外,一般不用別的注解代替。
13、如果在攔截請求中,我想攔截get方式提交的方法,怎么配置?
可以在@RequestMapping注解里面加上method=RequestMethod.GET。
14、怎樣在方法里面得到Request,或者Session?
直接在方法的形參中聲明request,SpringMVC就自動把request對象傳入。
15、如果想在攔截的方法里面得到從前臺傳入的參數,怎么得到?
直接在形參里面聲明這個參數就可以,但必須名字和傳過來的參數一樣。
16、如果前臺有很多個參數傳入,并且這些參數都是一個對象的,那么怎么樣快速得到這個對象?
直接在方法中聲明這個對象,SpringMVC就自動會把屬性賦值到這個對象里面。
17、SpringMVC中函數的返回值是什么?
返回值可以有很多類型,有String, ModelAndView。ModelAndView類把視圖和數據都合并的一起的。
18、SpringMVC用什么對象從后臺向前臺傳遞數據的?
通過ModelMap對象,可以在這個對象里面調用put方法,把對象加到里面,前臺就可以拿到數據。
19、怎么樣把ModelMap里面的數據放入Session里面?
可以在類上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。
20、SpringMvc里面攔截器是怎么寫的:
有兩種寫法,一種是實現HandlerInterceptor接口,另外一種是繼承適配器類,接著在接口方法當中,實現處理邏輯;然后在SpringMvc的配置文件中配置攔截器即可:
<!-- 配置SpringMvc的攔截器 -->
<mvc:interceptors>
<!-- 配置一個攔截器的Bean就可以了 默認是對所有請求都攔截 -->
<bean id="myInterceptor" class="com.zwp.action.MyHandlerInterceptor"></bean>
<!-- 只針對部分請求攔截 -->
<mvc:interceptor>
<mvc:mapping path="/modelMap.do" />
<bean class="com.zwp.action.MyHandlerInterceptorAdapter" />
</mvc:interceptor>
</mvc:interceptors>
21、注解原理:
注解本質是一個繼承了Annotation的特殊接口,其具體實現類是Java運行時生成的動態(tài)代理類。我們通過反射獲取注解時,返回的是Java運行時生成的動態(tài)代理對象。通過代理對象調用自定義注解的方法,會最終調用AnnotationInvocationHandler的invoke方法。該方法會從memberValues這個Map中索引出對應的值。而memberValues的來源是Java常量池
三、Mybatis篇
1、什么是MyBatis?
MyBatis是一個可以自定義SQL、存儲過程和高級映射的持久層框架。
2、講下MyBatis的緩存
MyBatis的緩存分為一級緩存和二級緩存,一級緩存放在session里面,默認就有,
二級緩存放在它的命名空間里,默認是不打開的,使用二級緩存屬性類需要實現Serializable序列化接口,
可在它的映射文件中配置<cache/>
3、Mybatis是如何進行分頁的?分頁插件的原理是什么?
1)Mybatis使用RowBounds對象進行分頁,也可以直接編寫sql實現分頁,也可以使用Mybatis的分頁插件。
2)分頁插件的原理:實現Mybatis提供的接口,實現自定義插件,在插件的攔截方法內攔截待執(zhí)行的sql,然后重寫sql。
舉例:select * from student,攔截sql后重寫為:select t.* from (select * from student)t limit 0,10
4、簡述Mybatis的插件運行原理,以及如何編寫一個插件?
1)Mybatis僅可以編寫針對ParameterHandler、ResultSetHandler、StatementHandler、
Executor這4種接口的插件,Mybatis通過動態(tài)代理,
為需要攔截的接口生成代理對象以實現接口方法攔截功能,
每當執(zhí)行這4種接口對象的方法時,就會進入攔截方法,
具體就是InvocationHandler的invoke()方法,當然,
只會攔截那些你指定需要攔截的方法。
2)實現Mybatis的Interceptor接口并復寫intercept()方法,
然后在給插件編寫注解,指定要攔截哪一個接口的哪些方法即可,
記住,別忘了在配置文件中配置你編寫的插件。
5、Mybatis動態(tài)sql是做什么的?都有哪些動態(tài)sql?能簡述一下動態(tài)sql的執(zhí)行原理不?
1)Mybatis動態(tài)sql可以讓我們在Xml映射文件內,
以標簽的形式編寫動態(tài)sql,完成邏輯判斷和動態(tài)拼接sql的功能。
2)Mybatis提供了9種動態(tài)sql標簽:trim|where|set|foreach|if|choose|when|otherwise|bind。
3)其執(zhí)行原理為,使用OGNL從sql參數對象中計算表達式的值,
根據表達式的值動態(tài)拼接sql,以此來完成動態(tài)sql的功能。
6、#{}和${}的區(qū)別是什么?
1)#{}是預編譯處理,${}是字符串替換。
2)Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值(有效的防止SQL注入);
3)Mybatis在處理${}時,就是把${}替換成變量的值。
7、為什么說Mybatis是半自動ORM映射工具?它與全自動的區(qū)別在哪里?
Hibernate屬于全自動ORM映射工具,
使用Hibernate查詢關聯對象或者關聯集合對象時,
可以根據對象關系模型直接獲取,所以它是全自動的。
而Mybatis在查詢關聯對象或關聯集合對象時,
需要手動編寫sql來完成,所以,稱之為半自動ORM映射工具。
8、Mybatis是否支持延遲加載?如果支持,它的實現原理是什么?
1)Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,
association指的就是一對一,collection指的就是一對多查詢。
在Mybatis配置文件中,
可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
2)它的原理是,使用CGLIB創(chuàng)建目標對象的代理對象,
當調用目標方法時,進入攔截器方法,
比如調用a.getB().getName(),
攔截器invoke()方法發(fā)現a.getB()是null值,
那么就會單獨發(fā)送事先保存好的查詢關聯B對象的sql,
把B查詢上來,然后調用a.setB(b),
于是a的對象b屬性就有值了,
接著完成a.getB().getName()方法的調用。
這就是延遲加載的基本原理。
9、MyBatis與Hibernate有哪些不同?
1)Mybatis和hibernate不同,它不完全是一個ORM框架,
因為MyBatis需要程序員自己編寫Sql語句,
不過mybatis可以通過XML或注解方式靈活配置要運行的sql語句,
并將java對象和sql語句映射生成最終執(zhí)行的sql,
最后將sql執(zhí)行的結果再映射生成java對象。
2)Mybatis學習門檻低,簡單易學,程序員直接編寫原生態(tài)sql,
可嚴格控制sql執(zhí)行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發(fā),
例如互聯網軟件、企業(yè)運營類軟件等,因為這類軟件需求變化頻繁,
一但需求變化要求成果輸出迅速。但是靈活的前提是mybatis無法做到數據庫無關性,
如果需要實現支持多種數據庫的軟件則需要自定義多套sql映射文件,工作量大。
3)Hibernate對象/關系映射能力強,數據庫無關性好,
對于關系模型要求高的軟件(例如需求固定的定制化軟件)
如果用hibernate開發(fā)可以節(jié)省很多代碼,提高效率。
但是Hibernate的缺點是學習門檻高,要精通門檻更高,
而且怎么設計O/R映射,在性能和對象模型之間如何權衡,
以及怎樣用好Hibernate需要具有很強的經驗和能力才行。
總之,按照用戶的需求在有限的資源環(huán)境下只要能做出維護性、
擴展性良好的軟件架構都是好架構,所以框架只有適合才是最好。
10、MyBatis的好處是什么?
1)MyBatis把sql語句從Java源程序中獨立出來,放在單獨的XML文件中編寫,
給程序的維護帶來了很大便利。
2)MyBatis封裝了底層JDBC API的調用細節(jié),并能自動將結果集轉換成Java Bean對象,
大大簡化了Java數據庫編程的重復工作。
3)因為MyBatis需要程序員自己去編寫sql語句,
程序員可以結合數據庫自身的特點靈活控制sql語句,
因此能夠實現比Hibernate等全自動orm框架更高的查詢效率,能夠完成復雜查詢。
11、簡述Mybatis的Xml映射文件和Mybatis內部數據結構之間的映射關系?
Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內部。
在Xml映射文件中,<parameterMap>標簽會被解析為ParameterMap對象,
其每個子元素會被解析為ParameterMapping對象。
<resultMap>標簽會被解析為ResultMap對象,
其每個子元素會被解析為ResultMapping對象。
每一個<select>、<insert>、<update>、<delete>
標簽均會被解析為MappedStatement對象,
標簽內的sql會被解析為BoundSql對象。
12、什么是MyBatis的接口綁定,有什么好處?
接口映射就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,
我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置.
13、接口綁定有幾種實現方式,分別是怎么實現的?
接口綁定有兩種實現方式,一種是通過注解綁定,就是在接口的方法上面加
上@Select@Update等注解里面包含Sql語句來綁定,
另外一種就是通過xml里面寫SQL來綁定,在這種情況下,
要指定xml映射文件里面的namespace必須為接口的全路徑名.
14、什么情況下用注解綁定,什么情況下用xml綁定?
當Sql語句比較簡單時候,用注解綁定;當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多
15、MyBatis實現一對一有幾種方式?具體怎么操作的?
有聯合查詢和嵌套查詢,聯合查詢是幾個表聯合查詢,只查詢一次,
通過在resultMap里面配置association節(jié)點配置一對一的類就可以完成;
嵌套查詢是先查一個表,根據這個表里面的結果的外鍵id,
去再另外一個表里面查詢數據,也是通過association配置,
但另外一個表的查詢通過select屬性配置。
16、Mybatis能執(zhí)行一對一、一對多的關聯查詢嗎?都有哪些實現方式,以及它們之間的區(qū)別?
能,Mybatis不僅可以執(zhí)行一對一、一對多的關聯查詢,
還可以執(zhí)行多對一,多對多的關聯查詢,多對一查詢,
其實就是一對一查詢,只需要把selectOne()修改為selectList()即可;
多對多查詢,其實就是一對多查詢,只需要把selectOne()修改為selectList()即可。
關聯對象查詢,有兩種實現方式,一種是單獨發(fā)送一個sql去查詢關聯對象,
賦給主對象,然后返回主對象。另一種是使用嵌套查詢,嵌套查詢的含義為使用join查詢,
一部分列是A對象的屬性值,另外一部分列是關聯對象B的屬性值,
好處是只發(fā)一個sql查詢,就可以把主對象和其關聯對象查出來。
17、MyBatis里面的動態(tài)Sql是怎么設定的?用什么語法?
MyBatis里面的動態(tài)Sql一般是通過if節(jié)點來實現,通過OGNL語法來實現,
但是如果要寫的完整,必須配合where,trim節(jié)點,where節(jié)點是判斷包含節(jié)點有
內容就插入where,否則不插入,trim節(jié)點是用來判斷如果動態(tài)語句是以and 或or
開始,那么會自動把這個and或者or取掉。
18、Mybatis是如何將sql執(zhí)行結果封裝為目標對象并返回的?都有哪些映射形式?
第一種是使用<resultMap>標簽,逐一定義列名和對象屬性名之間的映射關系。
第二種是使用sql列的別名功能,將列別名書寫為對象屬性名,
比如T_NAME AS NAME,對象屬性名一般是name,小寫,
但是列名不區(qū)分大小寫,Mybatis會忽略列名大小寫,
智能找到與之對應對象屬性名,你甚至可以寫成T_NAME AS NaMe,
Mybatis一樣可以正常工作。
有了列名與屬性名的映射關系后,Mybatis通過反射創(chuàng)建對象,
同時使用反射給對象的屬性逐一賦值并返回,那些找不到映射關系的屬性,是無法完成賦值的。
19、Xml映射文件中,除了常見的select|insert|updae|delete標簽之外,還有哪些標簽?
還有很多其他的標簽,<resultMap>、<parameterMap>、<sql>、
<include>、<selectKey>,加上動態(tài)sql的9個標簽,
trim | where|set | foreach | if | choose | when | otherwise | bind 等,
其中<sql>為sql片段標簽,通過<include>標簽引入sql片段,
<selectKey>為不支持自增的主鍵生成策略標簽。
20、當實體類中的屬性名和表中的字段名不一樣,如果將查詢的結果封裝到指定pojo?
1)通過在查詢的sql語句中定義字段名的別名。
2)通過<resultMap>來映射字段名和實體類屬性名的一一對應的關系。
21、模糊查詢like語句該怎么寫
1)在java中拼接通配符,通過#{}賦值
2)在Sql語句中拼接通配符 (不安全 會引起Sql注入)
22、通常一個Xml映射文件,都會寫一個Dao接口與之對應, Dao的工作原理,是否可以重載?
不能重載,因為通過Dao尋找Xml對應的sql的時候全限名+方法名的保存和尋找策略。
接口工作原理為jdk動態(tài)代理原理,運行時會為dao生成proxy,
代理對象會攔截接口方法,去執(zhí)行對應的sql返回數據。
23、Mybatis映射文件中,如果A標簽通過include引用了B標簽的內容,請問,B標簽能否定義在A標簽的后面,還是說必須定義在A標簽的前面?
雖然Mybatis解析Xml映射文件是按照順序解析的,但是,被引用的B標簽依然可以定義在任何地方,
Mybatis都可以正確識別。原理是,Mybatis解析A標簽,發(fā)現A標簽引用了B標簽,
但是B標簽尚未解析到,尚不存在,此時,Mybatis會將A標簽標記為未解析狀態(tài),
然后繼續(xù)解析余下的標簽,包含B標簽,待所有標簽解析完畢,
Mybatis會重新解析那些被標記為未解析的標簽,此時再解析A標簽時,
B標簽已經存在,A標簽也就可以正常解析完成了。
24、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?
不同的Xml映射文件,如果配置了namespace,那么id可以重復;
如果沒有配置namespace,那么id不能重復;畢竟namespace不是必須的,
只是最佳實踐而已。原因就是namespace+id是作為Map<String,
MappedStatement>的key使用的,如果沒有namespace,
就剩下id,那么,id重復會導致數據互相覆蓋。
有了namespace,自然id就可以重復,namespace不同,
namespace+id自然也就不同。
25、Mybatis中如何執(zhí)行批處理?
使用BatchExecutor完成批處理。
26、Mybatis都有哪些Executor執(zhí)行器?它們之間的區(qū)別是什么?
Mybatis有三種基本的Executor執(zhí)行器,SimpleExecutor、ReuseExecutor、BatchExecutor。
1)SimpleExecutor:
每執(zhí)行一次update或select,就開啟一個Statement對象,
用完立刻關閉Statement對象。
2)ReuseExecutor:
執(zhí)行update或select,以sql作為key查找Statement對象,
存在就使用,不存在就創(chuàng)建,用完后,
不關閉Statement對象,而是放置于Map
3)BatchExecutor:完成批處理。
27、Mybatis中如何指定使用哪一種Executor執(zhí)行器?
在Mybatis配置文件中,可以指定默認的ExecutorType執(zhí)行器類型,
也可以手動給DefaultSqlSessionFactory的創(chuàng)建SqlSession的方法傳遞ExecutorType類型參數。
28、Mybatis執(zhí)行批量插入,能返回數據庫主鍵列表嗎?
能,JDBC都能,Mybatis當然也能。
29、Mybatis是否可以映射Enum枚舉類?
Mybatis可以映射枚舉類,不單可以映射枚舉類,
Mybatis可以映射任何對象到表的一列上。
映射方式為自定義一個TypeHandler,
實現TypeHandler的setParameter()和getResult()接口方法。
TypeHandler有兩個作用,一是完成從javaType至jdbcType的轉換,
二是完成jdbcType至javaType的轉換,體現為setParameter()和getResult()兩個方法,
分別代表設置sql問號占位符參數和獲取列查詢結果。
30、如何獲取自動生成的(主)鍵值?
配置文件設置usegeneratedkeys 為true
31、在mapper中如何傳遞多個參數?
1)直接在方法中傳遞參數,xml文件用#{0} #{1}來獲取
2)使用 @param 注解:這樣可以直接在xml文件中通過#{name}來獲取
32、resultType resultMap的區(qū)別?
1)類的名字和數據庫相同時,可以直接設置resultType參數為Pojo類
2)若不同,需要設置resultMap 將結果名字和Pojo名字進行轉換
33、使用MyBatis的mapper接口調用時有哪些要求?
1)Mapper接口方法名和mapper.xml中定義的每個sql的id相同
2)Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
3)Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
4)Mapper.xml文件中的namespace即是mapper接口的類路徑。
34、Mybatis比IBatis比較大的幾個改進是什么?
1)有接口綁定,包括注解綁定sql和xml綁定Sql
2)動態(tài)sql由原來的節(jié)點配置變成OGNL表達式
3) 在一對一,一對多的時候引進了association,在一對多的時候引入了collection節(jié)點,
不過都是在resultMap里面配置
35、IBatis和MyBatis在核心處理類分別叫什么?
IBatis里面的核心處理類交SqlMapClient,MyBatis里面的核心處理類叫做SqlSession。
36、IBatis和MyBatis在細節(jié)上的不同有哪些?
1)在sql里面變量命名有原來的#變量# 變成了#{變量}
2)原來的$變量$變成了${變量}
3)原來在sql節(jié)點里面的class都換名字交type
4)原來的queryForObject queryForList 變成了selectOne selectList5)原來的別名設置在映射文件里面放在了核心配置文件里
參考博客如下:
https://www.cnblogs.com/yanggb/p/11004887.html
https://blog.csdn.net/a745233700/article/details/80963758
https://blog.csdn.net/eaphyy/article/details/71190441
https://www.cnblogs.com/lukelook/p/11099039.html
https://segmentfault.com/a/1190000013678579
https://zhuanlan.zhihu.com/p/74123351