【框架】- MyBatis基礎
mybatis
-
什么是mybatis
? orm的半自動化框架,自己封裝了jdbc,創建驅動,創建鏈接,創建statement等,采取mapper動態代理機制,使使用者只需要關注sql的編寫。
? mybatis的sql是通過xm或者注解來進行對欲生成的sql進行配置,再通過配置的類路勁反射找到類的對象,從而找到要執行的方法,獲取方法中的動態參數, 再將參數根據反射匹配#{}中字符串根據set方法寫入到sql中,從而組裝成完整的sql在進行執行。最后將執行的結果在映射成對象或者map集合返回回來。
-
mybatis優缺點:
-
優點:
- sql寫在文件中可以讓sql與代碼解析解耦,后期便于維護
- 相對于原生jdbc會減少大量冗余代碼
- 采取jdbc來鏈接數據庫,所以會兼容各種數據庫
- 便于與spring進行集成
- 提供了映射標簽,可以是對象與數據庫字段進行映射
-
缺點:
- sql需要自己編寫,工程量較大
- sql依賴數據庫,所以不便于數據庫的遷移
-
-
#{} ${} 區別
- #{} 代表預處理,會將#{}替換成?在調用preparStatement中的set方法進行賦值
- ${} 代表字符串替換,會將${}中的字符直接替換,一般用于表名,關鍵字等
-
通常一個mapper.xml文件,都會對應一個Dao接口,這個Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法能重載嗎?
- Dao接口就是Mappper接口,
- dao接口中的全類名就是配置文件中的namesqpce的值
- 接口的方法名對應映射文件中得id值
- 接口的方法參數就是sql的動態參數
- 通過類全名+方法名可以唯一確定映射文件中的對應的執行sql語句
- Dao接口就是Mappper接口,
-
如何進行分頁查詢,分頁插件原理是什么
- 第一中可以直接在sql中編寫limit語句
- mybatis是采取RowBounds對象來對返回的結果進行內存分頁,而非物理分頁,所以一般對于少數據查詢可以使用,若是大數據則不推薦使用。
-
Mybatis是否支持延遲加載?如果支持,它的實現原理是什么
- 僅支持association(一對一)和collection(一對多)進行延遲加載通過lazyLoadingEnabled=true|false
- 在調用目標方法時,進行攔截,若是目標方法中不需要獲取聚合對象的值,則進行攔截僅查詢第一條sql,若是用到聚合對象的值,則在獲取第一條sql的返回值來查詢第二條sql語句
-
Mybatis是如何將sql執行結果封裝為目標對象并返回的?都有哪些映射形式
- 通過resultMap來進行逐一映射數據庫列名和對象屬性名之間的關系
- 也可以給數據庫查詢語句中的列定義個別名來進行映射
- 獲取映射關系后通過反射來獲取對象調用set方法來給對象賦值并返回
-
Mybatis動態sql有什么用?執行原理?有哪些動態sql?
- 動態sql可以在映射文件中以標簽形式來編寫sql
- 提供的標簽有:trim | where | set | foreach | if | choose | when | otherwise | bind、
-
Xml映射文件中,除了常見的select | insert | updae | delete標簽之外,還有哪些標簽?
標簽 定義一個sql片段 有個id屬性 標簽 可以應用 sql標簽的片段sql 標簽 定義返回值進行映射配置 定義返回值類型 不支持自增的主鍵生成策略標簽
-
使用MyBatis的mapper接口調用時有哪些要求
- 接口方法名與映射文件mapper.xml中的sql的id 一致
- Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
- Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
- Mapper.xml文件中的namespace即是mapper接口的類全名路徑
-
模糊查詢like語句該怎么寫
-
直接在sql中寫入如下:
// 容易引發sql注入 <select id=”selectlike”> select * from foo where bar like '%${}%' </select> -
采取傳參還有%%方式進行配置:
// 調用方法時直接傳參含有%% 比較麻煩 sqlSession.selectList("類路徑","%zht%"); <select id=”selectlike”> select * from foo where bar like #{} </select> -
直接在sql中采取concat進行拼接處理
<select id=”selectlike”> select * from foo where bar like concat('%',#{},'%') </select>
-
-
當實體類中的屬性名和表中的字段名不一樣 ,怎么辦
- 查詢語句字段起別名使別名與屬性名一致
- 通過
來映射字段名和實體類屬性名的一一對應的關系
-
如何獲取自動生成的(主)鍵值
-
insert方法中總會返回一個值,代表插入的行數
-
獲取自增主鍵值可以在標簽中配置:usegeneratedkeys=”true”如下:
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”> insert into names (name) values (#{name}) </insert> int rows = mapper.insertname(name); // 完成后,id已經被設置到對象中 system.out.println(“rows inserted = ” + rows); system.out.println(“generated key value = ” + name.getid());
-
-
在mapper中如何傳遞多個參數
-
直接傳遞多個參數,sql語句寫成#{0},#{1}進行匹配
//DAO層的函數 Public UserselectUser(String name,String area); //對應的xml,#{0}代表接收的是dao層中的第一個參數,#{1}代表dao層中第二參數,更多參數一致往后加即可。 <select id="UserselectUser"resultMap="BaseResultMap"> select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1} </select> -
直接傳遞參數,在參數前面協商注解
//DAO層的函數 Public UserselectUser(@param("name") String name, @param("area") String area); //對應的xml,#{0}代表接收的是dao層中的第一個參數,#{1}代表dao層中第二參數,更多參數一致往后加即可。 <select id="UserselectUser"resultMap="BaseResultMap"> select * fromuser_user_t whereuser_name = #{name} anduser_area=#{area} </select> -
參數封裝成map
Map<String, Object> map = new HashMap(); map.put("name", name); map.put("area", area); return sqlSession.selecOne("UserselectUser", map); <select id="UserselectUser"resultMap="BaseResultMap"> select * fromuser_user_t whereuser_name = #{name} anduser_area=#{area} </select>
-
-
一對一、一對多的關聯查詢
<mapper namespace="com.lcb.mapping.userMapper"> <!--association 一對一關聯查詢 --> <select id="getClass" parameterType="int" resultMap="ClassesResultMap"> select * from class c,teacher t where c.teacher_id=t.t_id and c.c_id=#{id} </select> <resultMap type="com.lcb.user.Classes" id="ClassesResultMap"> <!-- 實體類的字段名和數據表的字段名映射 --> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" javaType="com.lcb.user.Teacher"> <id property="id" column="t_id"/> <result property="name" column="t_name"/> </association> </resultMap> <!--collection 一對多關聯查詢 --> <select id="getClass2" parameterType="int" resultMap="ClassesResultMap2"> select * from class c,teacher t,student s where c.teacher_id=t.t_id and c.c_id=s.class_id and c.c_id=#{id} </select> <resultMap type="com.lcb.user.Classes" id="ClassesResultMap2"> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" javaType="com.lcb.user.Teacher"> <id property="id" column="t_id"/> <result property="name" column="t_name"/> </association> <collection property="student" ofType="com.lcb.user.Student"> <id property="id" column="s_id"/> <result property="name" column="s_name"/> </collection> </resultMap> </mapper> -
MyBatis實現一對一/一對多有幾種方式?具體怎么操作的
- 有聯合查詢和嵌套查詢,聯合查詢是幾個表聯合查詢,只查詢一次, 通過在resultMap里面配置association節點配置一對一/ collection節點配置一對多的類就可以完成
- 嵌套查詢是先查一個表,根據這個表里面的結果的 外鍵id,去再另外一個表里面查詢數據,也是通過association/collection配置,但另外一個表的查詢通過select屬性配置
-
什么是MyBatis的接口綁定?有哪些實現方式
- 接口綁定,就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定
- 實現方式
- 一種是通過注解綁定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql語句來綁定
- 通過xml里面寫SQL來綁定, 在這種情況下,要指定xml映射文件里面的namespace必須為接口的全路徑名
-
MyBatis與Hibernate有哪些不同
- MyBatis需要程序員自己寫sql Hibernate不需要
- Mybatis無法做到數據庫無關性如果需要實現支持多種數據庫的軟件,則需要自定義多套sql映射文件,工作量大 而 Hibernate 可以
浙公網安備 33010602011771號