Java面试——MyBatis系列总结
文章目錄:
1.MyBatis是什么?
2.JDBC編程有哪些缺陷?MyBatis又是如何改進的?
3.MyBatis與Hibernate的區別在哪?
4.MyBatis的優缺點
5.請說說MyBatis的工作原理
6.MyBatis的架構設計是怎樣的?
7.#{}和${}的區別
8.模糊查詢like語句該怎么寫
9.如何獲取生成的主鍵?
10.當實體類中的屬性名和表中的字段名不一樣怎么辦?
11.什么是MyBatis的接口綁定?有哪些實現方式?
12.使用MyBatis的mapper接口調用時有哪些要求?
13.最佳實踐中,通常一個Xml映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法能重載嗎
14.MyBatis動態sql是做什么的?都有哪些動態sql?能簡述一下動態sql的執行原理不?
15.MyBatis的一級、二級緩存是什么?
1.MyBatis是什么?
MyBatis是一款優秀的dao持久層框架、一個半ORM(對象關系映射)框架。它支持定制化SQL、存儲過程、高級映射、緩存機制,同時MyBatis幾乎避免了JDBC代碼中手動設置參數以及獲取結果集等繁雜操作的過程。
2.JDBC編程有哪些缺陷?MyBatis又是如何改進的?
- JDBC編程中頻繁創建、釋放數據庫連接對象,容易造成系統資源浪費,影響系統性能??梢允褂眠B接池解決這個問題。
? 解決:在mybatis-config.xml中配置數據庫連接池,使用連接池管理數據庫連接。
- JDBC編程中 sql 語句寫在代碼中造成代碼不易維護,實際應用場景中sql的變化可能較大,sql變動需要改變java代碼。
? 解決:將SQL語句配置在XXXXmapper.xml映射文件中,與java代碼分離。
- JDBC編程中向sql語句傳參數麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參數一一對應。
? 解決:Mybatis中自動將java對象映射至sql語句。
- JDBC編程中對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成pojo對象解析比較方便。
? 解決:Mybatis中自動將sql執行結果映射至java對象。
3.MyBatis與Hibernate的區別在哪?
首先要提到一個詞ORM。ORM(Object Relational Mapping)對象關系映射,是一種為了解決關系型數據庫數據與簡單Java對象(POJO)的映射關系的技術。
相同點:
- 都是對jdbc的封裝,都是持久層的框架,都用于dao層的開發。
不同點:
- Hibernate是全自動ORM映射工具,Hibernate 對SQL語句封裝,提供了日志、緩存、級聯(級聯比 MyBatis 強大)等特性,此外還提供 HQL(Hibernate Query Language)操作數據庫,數據庫無關性支持好,但會多消耗性能。使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。
- MyBatis 在查詢關聯對象或關聯集合對象時,需要手動編寫 SQL,支持動態 SQL、處理列表、動態生成表名、支持存儲過程。所以,稱之為半自動ORM映射工具。
4.MyBatis的優缺點
優點
與傳統的數據庫訪問技術相比,ORM有以下優點:
- 基于SQL語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影響,SQL寫在XML里,解除SQL與程序代碼的耦合,便于統一管理;提供XML標簽,支持編寫動態SQL語句,并可重用。
- 與JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手動開關連接。
- 很好的與各種數據庫兼容(因為MyBatis使用JDBC來連接數據庫,所以只要JDBC支持的數據庫MyBatis都支持)。
- 提供映射標簽,支持對象與數據庫的字段映射;提供對象關系映射標簽,支持對象關系組件維護。
- 能夠與Spring很好的集成。
缺點
- SQL語句的編寫工作量較大,尤其當字段多、關聯表多時,對開發人員編寫SQL語句的功底有一定要求。
- SQL語句依賴于數據庫,導致數據庫移植性差,不能隨意更換數據庫。
5.請說說MyBatis的工作原理
通過加載mybatis全局配置文件以及mapper映射文件初始化configuration對象和Executor對象(通過全局配置文件中的defaultExecutorType初始化);
創建一個defaultSqlSession對象,將configuration對象和Executor對象注入給defaulSqlSession對象中;
defaulSqlSession通過getMapper()獲取mapper接口的代理對象mapperProxy(mapperProxy中包含defaultSQLSession對象)
執行增刪改查:
- 通過defaulSqlSession中的屬性Executor創建statementHandler對象;
- 創建statementHandler對象的同時也創建parameterHandler和resultSetHandler;
通過parameterHandler設置預編譯參數及參數值;
調用statementHandler執行增刪改查;
通過resultsetHandler封裝查詢結果。
6.MyBatis的架構設計是怎樣的?
- API接口層:提供給外部使用的接口API,開發人員通過這些本地API來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。
- 數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操作。
- 基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的數據處理層提供最基礎的支撐。
- 引導層:加載xml配置和Java配置。
7.#{}和${}的區別
- #{}是占位符,預編譯處理,可以防止SQL注入;${}是拼接符,字符串替換,沒有預編譯處理,不能防止SQL注入。
- Mybatis在處理#{}時,#{}傳入參數是以字符串傳入,會將SQL中的#{}替換為?號,調用PreparedStatement的set方法來賦值;Mybatis在處理時,是原值傳入,就是把{}時,是原值傳入,就是把時,是原值傳入,就是把{}替換成變量的值,相當于JDBC中的Statement編譯。
- #{} 的變量替換是在DBMS 中,變量替換后,#{} 對應的變量自動加上單引號;的變量替換是在DBMS外,變量替換后,{} 的變量替換是在 DBMS 外,變量替換后,的變量替換是在DBMS外,變量替換后,{} 對應的變量不會加上單引號。
8.模糊查詢like語句該怎么寫
- “%”#{question}"%" 注意:因為#{…}解析成sql語句時候,會在變量外側自動加單引號’ ',所以這里 % 需要使用雙引號" ",不能使用單引號 ’ ',不然會查不到任何結果。
- ‘%${question}%’ 可能引起SQL注入,不推薦。
- CONCAT(’%’,#{question},’%’) 使用CONCAT()函數,推薦。
- 使用bind標簽。
9.如何獲取生成的主鍵?
對于支持主鍵自增的數據庫(MySQL)
<!-- useGeneratedKeys 設置為"true"表明 MyBatis 要獲取由數據庫自動生成的主鍵,keyColumn指定數據庫主鍵,keyProperty指定 Java 實體類中對應的主鍵字段 --> <insert id="insertUser" useGeneratedKeys="true" >keyProperty="userId" >insert into user(user_name, user_password, create_time)values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP}) </insert>parameterType 可以不寫,Mybatis可以推斷出傳入的數據類型。如果想要訪問主鍵,那么parameterType 應當是java實體或者Map。這樣數據在插入之后可以通過java實體或者Map來獲取主鍵值。
10.當實體類中的屬性名和表中的字段名不一樣怎么辦?
第1種:通過在查詢的SQL語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
<select id="getEmpById" resultType="com.szh.bean.Employee">select id,last_name lastName,email,genderfrom employeewhere id = #{id} </select>第2種:通過<resultMap>來映射字段名和實體類屬性名的一一對應關系。
<resultMap id="myMap" type="com.szh.bean.Employee"><id column="id" property="id"/><result column="last_name" property="lastName"/><result column="email" property="email"/><result column="gender" property="gender"/> </resultMap>第3種:在mybatis全局配置文件中開啟駝峰命名規則。
<settings><setting name="mapUnderscoreToCamelCase" value="true"/> </settings>11.什么是MyBatis的接口綁定?有哪些實現方式?
接口綁定,就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們調用接口方法的時候,最終會執行綁定的SQL語句。
接口綁定有兩種實現方式,當Sql語句比較簡單時候,可以使用注解綁定,當SQL語句比較復雜時候,一般用xml綁定的比較多。
- 通過注解綁定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql語句來實現接口綁定;
- 通過在xml里面寫SQL語句來實現綁定, 在這種情況下,要指定xml映射文件里面的namespace必須為接口的全限定類名,同時接口的方法名和SQL語句的id一一對應。
12.使用MyBatis的mapper接口調用時有哪些要求?
- Mapper.xml文件中的namespace應該是對應mapper接口的全限定類名。
- Mapper接口方法名和mapper.xml中定義的sql語句id一一對應。
- Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql語句的parameterType的類型相同。
- Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql語句的resultType的類型相同。
13.最佳實踐中,通常一個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中,每一個<select>、<insert>、<update>、<delete>標簽,都會被解析為一個MappedStatement對象。
Dao接口里的方法,是不能重載的,因為是全限定類名+方法名的保存和尋找策略,需要保證全限定類名+方法名的唯一性。(重載了話,方法名一定是重復的)
Dao接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Dao接口生成代理對象proxy,代理對象proxy會攔截接口方法調用,轉而執行方法對應的sql語句,然后將sql執行結果返回。
14.MyBatis動態sql是做什么的?都有哪些動態sql?能簡述一下動態sql的執行原理不?
Mybatis動態sql可以讓我們在xml映射文件內,以標簽的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標簽trim|where|set|foreach|if|choose|when|otherwise|bind。
其執行原理為,使用OGNL(對象導航圖語言Object Graph Navigation Language)從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。
15.MyBatis的一級、二級緩存是什么?
- 一級緩存:采用 PerpetualCache,HashMap 存儲。MyBatis默認打開一級緩存,其存儲作用域為 當前sqlSession會話對象,當 sqlSession flush 或 close 之后,該 sqlSession 中的所有 Cache 就將清空??梢哉{用clearCache();//手動清理緩存。
- 二級緩存:默認也是采用 PerpetualCache,HashMap 存儲,不同之處在于二級緩存的存儲作用域為 Mapper(Namespace),并且可自定義存儲源,如 Ehcache。默認不打開二級緩存,開啟二級緩存之后(在mybatis主配置文件中添加<setting name="cacheEnabled" value="true"/>;其次在對應的mapper映射文件中添加 ),對應的實體類需要實現Serializable序列化接口(可用來保存對象的狀態)。
- 對于緩存數據更新機制,當某一個作用域(一級緩存 Session/二級緩存Namespaces)進行了C/U/D 操作后,默認該作用域下所有緩存將被清理掉。
總結
以上是生活随笔為你收集整理的Java面试——MyBatis系列总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java joda 获取utc时间_ja
- 下一篇: java读取pi_(树莓派csi相机)使