mybatis框架详解
一、簡介
1、歷史
mybatis的前身是apache ibatis,2010年由ASF轉移到google code,從ibatis3.x改名為mybatis,2013年轉移到github。mybatis是由java實現的持久層框架。
2、mybatis的特性
mybatis是一個半自動化的持久層框架,
可以注解配置、映射xml文件中編寫動態sql語句。通常使用xml編寫sql。
mybatis是對jdbc封裝的框架,幾乎不需要jdbc操作
mybatis提供面向接口編程,持久層只需要一個接口,不需要實現類。
3、和其他持久層框架 的比較
jdbc : 硬編碼,在java語句中寫sql,耦合度高
hibernate、jpa:自動框架,由框架生成sql語句,不需要人為編寫,靈活度較差,高度定制化的sql語句需要跳過框架。
mybatis:半自動化的框架,可以注解配置、xml配置。
二、映射文件
1、mybatis的映射文件結構
<!DOCTYPE mapper ...> <mapper namespace="com.sly.ecs.business.mapper.mission.MissionMapper"><insert id="insertBatch" parameterType="list" ...> <select id="selectMission" parameterType="int" resultMap="BaseResultMap" ...> </mapper>通過頂級標簽中的namespace屬性來指定對應的mapper接口,
通過子標簽的id屬性來指定對應的抽象方法。
2、參數
(1)傳入參數的情形:
①、mapper接口方法的參數是單個:
xml文件用#{ },來取值,需要注意{ }來取值,需要注意來取值,需要注意{ }要用單引號。
{}中的名稱是任意的,因為只有一個參數,無論取值時叫什么,都能夠取到值。
②、mapper接口方法的參數是多個:
會用Map集合保存參數,鍵是由mybatis框架自動生成
1)xml文件可以用 arg0 、arg1 。。。 獲取對應位置的參數
2)xml文件可以用 param1 、param2 。。。 獲取對應位置的參數
也可以交叉使用,例如 arg0、 param2
③、mapper接口方法的參數是多個,可以放到一個Map集合里
鍵是由開發者人為設置。
在xml映射文件里根據人為設置的鍵獲取參數。
例如:在600ly公司代碼中使用 GenericQueryParam裝載參數。
④、mapper接口方法的參數是實體類
xml文件里根據實體類的屬性獲取屬性值。
補充知識:實體類中有set、get方法的才算做屬性,不是按照全局變量來定義的。
⑤、mapper接口方法傳入@Param注解參數
參數會保存到Map集合,以@Param的值作為鍵,xml文件以Map的鍵來獲取參數。
歸類:
①、參數加上@Param注解 傳入方法
②、參數裝進Map或者實體類 傳入方法
(2)獲取參數的兩種方式:(jdbc原生寫法)
${} 字符串拼接。不會帶上單引號。注意要手動加上單引號。
#{} 占位符賦值。會帶上單引號。不需要手動加上單引號。
示例:
①、常規
②、Mybatis處理模糊查詢
role_name LIKE CONCAT('%',#{roleName},'%') role_name LIKE '%${roleName}%' role_name LIKE "%"#{roleName}"%"③、in范圍查詢:
String ids=“1,4,25”;
④、動態設置表名、字段名、排序關鍵字:
select * from ${tableName} ORDER BY ${sortColumn} ${sortOrder}總結:
sql語法中需要引號的 盡量使用#{},或者${} 手動加上引號。 例如字符串、日期等類型的值。sql語法中不需要引號的 使用${} ,不用手動加上引號。例如in范圍查詢、表名、字段、排序關鍵字。3、返回值
(1)增刪改操作的返回值可以是void、int
int類型的返回值是sql語句影響的數據條數。
(2)查詢操作的返回值在xml映射文件標簽的屬性resultType或resultMap里設置。
resultType是單個類型,resultMap是人為設置的字段-屬性的映射關系。
select查詢結果的情況:
①、如果查詢的結果是一條記錄
查詢結果可以用實體類或者list 或者 map集合接收。
用map集合接收,查詢結果的字段作為鍵,字段對應的值作為值。
②、如果查詢的結果是多條記錄
1)可以用List<> 接收。
List<實體類>或者 List<Map<String,Object>接收
不能用單個實體類接收多條記錄。會報TooManyResultsException。
2)可以用一個map集合接收。
在@MapKey(“”) 注解的value屬性中指定某個字段的值作為map的鍵。
例如:@MapKey(“id”)
③、查詢結果是單行單列,可以用基本數據或String類型接收。
4、類型別名
Mybatis框架對常用的類型設置了對應的別名,用來替代全類名,簡化代碼。
簡記:基本數據類型前面加下劃線,復雜數據類型為全小寫。
5、添加操作,獲取自增主鍵
User u=new User(null,"yang","123456","男"); userMapper.insertUser(u); u.getId(); int insertUser(User user); <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">insert into t_user values(null,#{username},#{password},#{sex} ) </insert>useGeneratedKeys:設置當前的sql使用了自增的主鍵。
keyProperty:將自增的主鍵的值賦值給傳輸到映射文件中參數的某個屬性。
6、解決字段名和屬性名不一致的情況
1)在Mapper.xml文件里給sql語句的字段起別名
emp_name as empName
2)在mybatis配置文件設置 下劃線轉換為駝峰式。
3)在Mapper.xml文件里設置結果映射
<resultMap id="BaseResultMap" type="User" ><id property="pkId" colume="pk_id"/><result property="userName" colume="user_name"/><result property="password" colume="password"/><result property="sex" colume="sex"/><result property="email" colume="email"/> </resultMap>處理多對一 映射關系:
例:dept部門表和emp員工表是一對多的關系。在Emp實體類中加入Dept dept屬性。
需要將查詢結果字段裝到Emp類中。
方式1:設置級聯映射
方式2:association
<resultMap id="empAndDeptMap" type="Emp" ><id property="eid" colume="eid"/><result property="empName" colume="emp_name"/><result property="address" colume="address"/><result property="sex" colume="sex"/><result property="email" colume="email"/><association property="dept" javaType="Dept"><id property="did" colume="did"/><result property="deptName" colume="dept_name"/></association> </resultMap>方法3:分步查詢
處理一對多 映射關系:
三、動態sql
1、where、 if 標簽
if 標簽:對標簽中test屬性的表達式 進行判斷,為true則顯示標簽內的過濾條件,為false則不顯示標簽內的過濾條件。
where標簽中 沒有過濾條件,不加where關鍵字;
有過濾條件,加上where關鍵字,并將第一個條件前邊的and 或者or 關鍵字刪掉。
如果 第2、3個if標簽存在,則生成的動態sql是
SELECT * FROM t_project_role where pk_id != #{roleId} OR role_type = #{roleType}2、trim 標簽
有四個屬性。
prefix,suffix:給trim標簽里的內容加上前、后綴。
prefixoverrides,suffixoverrides:給trim標簽里的內容 前或后 去掉內容。
生成的動態sql是
SELECT * FROM t_project_role where role_name != #{roleName }3、choose、when、otherwise標簽
相當于java語言中if…else if…else 條件判斷代碼塊。
when 標簽對test屬性值進行判斷,值為true則作為動態sql的條件,不再判斷后面的條件。所以標簽里的條件不需要加and或者or 。
值為false則判斷后面的條件。如果when標簽中的test 屬性值都為false,則將otherwise標簽作為條件。
when標簽至少有一個,otherwise標簽最多有一個。
<select id="findUserByChoose" parameterType="domain.User" resultType="domain.User">select * from USER<where><choose><when test="username!=null and username!=''">username=#{username}</when><when test="sex!=null and sex!=''">sex=#{sex}</when><otherwise>did=1</otherwise></choose></where> </select>4、foreach 遍歷集合、數組
(1)in 范圍查找
DELETE FROM t_code WHERE pk_id IN <foreach collection="list" item="pkId" open="(" close=")" separator="," >#{pkId} </foreach> DELETE FROM t_code WHERE pk_id IN (12,23,55,86)(2)批量添加
INSERT INTO t_user(pk_id, name, sex, age) values <foreach collection="list" item="user" separator=",">( null, #{user.username}, #{user.sex}, #{user.age} ) </foreach>5、sql
寫一些常用的sql塊
例如:
四、mybatis緩存
1、一級緩存
使用同一個SqlSession,根據相同的查詢條件,只在第一次查詢時執行sql語句,之后每次查詢,都使用mybatis緩存的結果數據。
一級緩存失效的情形:
(1)不同的SqlSession對應不同的一級緩存
(2)同一個SqlSession ,查詢條件不同
(3)同一個SqlSession ,兩次查詢之間有增刪改操作
(4)同一個SqlSession ,兩次查詢之間清理過緩存clearCache()
2、二級緩存
使用同一個SqlSessionFactory,只在第一次查詢時執行sql語句,之后每次查詢,都是用mybatis二級緩存。
二級緩存開啟的條件:
(1)在核心配置文件中加上cacheEnabled="true"全局屬性
(2)在映射文件加上 標簽
(3)在兩次查詢之間,對SqlSession 進行commit()或close()
(4)查詢結果轉換的實體類型要實現序列化接口。
失效的情形:在兩次查詢之間,執行任意的增刪改操作,一級和二級緩存都會失效。
3、mybatis緩存的查詢順序
(1)先在二級緩存中查找
(2)二級緩存沒有,則在一級緩存中查找
(3)一級緩存中沒有,則到數據庫中查找
(4)SqlSession關閉之后,一級緩存中的數據保存到二級緩存中。
mybatis是持久層框架,做緩存功能不是很擅長,有開放的接口可以使用第三方緩存工具。只能替代mybatis的二級緩存。例如EHCache。
五、mybatis逆向工程
正向工程:根據實體類 生成數據庫表。例如Hibernate框架
逆向工程:根據數據庫表生成實體類、映射文件、mapper接口。
mybatis的逆向工程分為簡易版和全面版。
簡易版包括五個增刪改查方法。其中查詢方法包括查詢全部和根據id查找。
總結
以上是生活随笔為你收集整理的mybatis框架详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python实现栈及栈在四则运算中的应用
- 下一篇: vxe-table踩坑,表格操作列按钮不