1、什么是 MyBatis?
MyBatis 是一款優秀的支持自定義 SQL 查詢、存儲過程和高級映射的持久層框架,消除了 幾乎所有的 JDBC 代碼和參數的手動設置以及結果集的檢索 。 MyBatis 可以使用 XML,或注解進 行配置和映射,MyBatis 通過將參數映射到配置的 SOL,形成最終執行的 SOL語句 ,最后將執行SOL的結果映射成Java對象返回。
2、Mybatis具有以下優點
(1) 小巧,學習成本低,會寫 SQL上手就很快了。
(2) 比 JDBC,基本上配置好了,大部分的工作量就專注在 SQL 的部分。
(3) 方便維護管理,SQL 不需要在Java代碼中找,SQL代碼可以分離出來,重用。
(4) 接近 JDBC, 靈活,支持動態 SQL。
(5) 支持對象與數據庫ORM 字段關系映射
3、Mybatis 的缺點如下
(1) SQL語句的編寫工作量較大,尤其當字段多、關聯表多時,對開發人員編寫SQL語句的功底有一定要求。
(2) SQL語句依賴于數據庫,導致數據庫移植性差,不能隨意更換數據庫。
4、MyBatis框架適用場合:
如果你需要一個靈活的、可以動態生成映射關系的框架,如互聯網項目,MyBatis將是不錯的選擇。
5、MyBatis與Hibernate有哪些不同?
Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句。
Mybatis直接編寫原生態sql,可以嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,因為這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件,則需要自定義多套sql映射文件,工作量大。
Hibernate對象/關系映射能力強,數據庫無關性好,對于關系模型要求高的軟件,如果用hibernate開發可以節省很多代碼,提高效率。
6、#{}和KaTeX parse error: Expected 'EOF', got '#' at position 11: {}的區別是什么? #?{}是預編譯處理,{}是字符串替換。
Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;
Mybatis在處理 時,就是把 {}時,就是把 時,就是把{}替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
7、Mybatis 中9個動態標簽是?
(1) if:結合 test 屬性使用,當參數滿足條件才會執行某個條件。
(2) choose(when、oterwise):相當于java 中的 if else,choose標簽是按順序判斷其內部when標簽中的test條件是否成立,如果有一個成立,則choose結束;如果所有的when條件都不滿足時,則執行otherwise中的SQL。類似于java的switch語句。
(3) trim (where、set):輔助條件標簽,結合 if 標簽使用,用于 SQL拼接問題。
(4) foreach:循環語句,批量操作時遍歷使用。
(5) bind:創建一個變量并將其綁定到上下文,防止SQL注入等。
九大標簽在項目中的具體使用可參考以下資料,我就不羅列了:
MyBatis的9種動態標簽詳解
8、xml 映射文件中,有哪些標簽?
(1) select:映射查詢操作。
(2) insert:映射插入操作。
(3) update:映射更新操作。
(4) delete:映射刪除操作。
(5) resultMap:定義結果集映射規則,將數據庫查詢結果與Java對象屬性進行映射。
(6) parameterMap:已廢棄,用于舊版的參數映射,現代MyBatis推薦直接在#{}中使用參數名。
(7)selectKey:在插入操作后立即執行一個SELECT語句以獲取自動生成的關鍵字(如序列ID或IDENTITY列),主要用于不支持自動返回主鍵值的數據庫系統。
(8) sql:定義可重用的SQL片段,可以被其他語句引用。
外加上述9個動態標簽,一同組成了 xml 文件的標簽。
9、當實體類中的屬性名和表中的字段名不一樣,怎么辦 ?
第1種:通過在查詢的 sql 語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”> select order_id id, order_num orderNum ,order_price price form orders where order_id=#{id};
</select>
第2種:通過來映射字段名和實體類屬性名的一一對應的關系。
<select id="getOrder" parameterType="int" resultMap="orderresultmap"> select * from orders where order_id=#{id}
</select>
<resultMap type=”me.gacl.domain.order” id=”orderresultmap”> <!–用id屬性來映射主鍵字段–> <id property=”id” column=”order_id”> <!–用result屬性來映射非主鍵字段,property為實體類屬性名,column為數據表中的屬性–> <result property = “orderNum” column =”order_num”/> <result property=”price” column=”order_price” />
</reslutMap>
10、like模糊查詢怎么寫?
(1) ‘%${value}%‘不推薦
(2) CONCAT(’%’,#{value},%) 推薦
(3) like '%‘1l #{value}ll’%
(4) 使用bind ,例如 like #{pattern)
11、Mybatis的分頁原理
Mybatis 使用 RowBounds 對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁,所以一般不會使用。可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。
分頁插件的原理就是使用 MyBatis 提供的插件接口,實現自定義插件,在插件的攔截方法內,攔截待執行的SQL,然后根據設置的 dialect(方言),和設置的分頁參數,重寫SQL ,生成帶有分頁語句的SQL,執行重寫后的SQL,從而實現分頁。
舉例:select * from student,攔截sql后重寫為:select t.* from (select * from student)t limit 0,10。
12、如何獲取自動生成的(主)鍵值?
(1) 使用注解:
@Options(useGeneratedKeys =true, keyProperty ="id”)
int insert( );
(2) 基于Xml:
<insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id"parameterType="person" >INSERT INTO person(name, pswd)VALUE (#{name}, #{pswd})
</insert>
13、一個 Xml 映射文件,都會寫一個 Dao 接口與之對應,這個 Dao 接口的工作原理是什么?
Dao 接口就是人們常說的 Mapper 接口,接口的全限名,就是映射文件中的 namespace 的值,接口的方法名就是映射文件中 MappedStatement 的 id 值,接口方法內的參數就是傳遞給 sql 的參數。
接口里的方法是不能重載的,因為是全限名+方法名的保存和尋找策略。
Dao接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行接口方法所對應的MappedStatement所代表的sql,然后將sql執行結果返回。
MappedStatement:MappedStatement維護了一條 <select|update|delete|insert>節點的封裝,包括了傳入參數映射配置、執行的SQL語句、結果映射配置等信息。
14、在mapper中如何傳遞多個參數?
(1) 第一種
// DAO層的函數
Public UserselectUser(String name,String area);
// 對應的xml,#{0}代表接收的是dao層中的第一個參數,#{1}代表dao層中第二參數,更多參數一致往后加即可。
<select id="selectUser"resultMap="BaseResultMap"> select * fromuser_user_t where user_name = #{0} and user_area =#{1}
</select>
(2) 第二種:使用 @param 注解:
public interface usermapper { user selectUser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword); }
// 然后,就可以在xml像下面這樣使用(推薦封裝為一個map,作為單個參數傳遞給mapper):
<select id=”selectUser” resulttype=”user”> select id, username, hashedpassword from some_table where username = #{username} and hashedpassword = #{hashedpassword}
</select>
(3) 第三種:多個參數封裝成map,然后在 xml 中通過 #{map的key}取值
15、什么是MyBatis的接口綁定,有哪些實現方式?
接口綁定,就是在 MyBatis 中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們直接調用接口方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設置。
接口綁定有兩種實現方式:
通過注解綁定,就是在接口的方法上面加上 @Select、@Update 等注解,里面包含Sql語句來綁定;
通過xml里面寫SQL來綁定, 在這種情況下,要指定xml映射文件里面的 namespace 必須為接口的全路徑名。當Sql語句比較簡單時候,用注解綁定, 當SQL語句比較復雜時候,用xml綁定,一般用xml綁定的比較多。
寫在最后,現在有一款 MyBatis-Plus框架, 完美兼容MyBatis,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。具體使用大家可以參考官方文檔:MyBatis-Plus 文檔