一、映射文件解析
- 獲取自增主鍵的值
- 參數處理封裝
- 查詢sql映射解析
1、獲取自增主鍵的值
<insert id="addOkrRole" parameterType="com.tan.bo.OkrRole" useGeneratedKeys="true" keyProperty="id">
INSERT INTO okr_role(role_id, role_name, create_time, update_time, create_person, update_person)
VALUES (#{role_id},#{role_name},#{create_time},#{update_time},#{create_person},#{update_person})
</insert>
parameterType:參數類型可以省略 useGeneratedKeys="true":使用自增主鍵獲取主鍵值策略。 keyProperty:指定對應主鍵屬性,也就是mybatis獲取到主鍵值後,將這個值封裝給Javabean的哪個屬性。
2、參數處理封裝
(1)、單個參數
單個參數:不會做特殊處理 #{}:取出值,在mapsql映射文件中的sql參數可以隨意命名。
(2)、多個參數
多個參數會做特殊化處理,對個參數會被封裝成一個map
傳參的方式有多種:
1、使用參數的索引:key param1,param2...... value:傳入的參數值。
select * from okr_role where id = #{param1} and name =#{param2}
2、使用命名參數的方式:明確指定封裝參數時map的key:@Param("id")
public OkrRole getInfo(@Param("id") Integer id, @Param("name") String name);
3、可以直接傳入POJO:#{屬性名},取出傳入的pojo的屬性值
public OkrRole getInfo(OkrRole OkrRole);
4、如果對個參數不是業務模型中的數據,沒有對應的pojo,爲了方便,我們可以傳入map
#{key}取出map中對應的值。
如果對個參數不是業務模型中的數據,但是經常使用,就用map這種方式,比如我們的分頁參數。
public OkrRole getInfo(Map<String, OkrRole>);
(3)、參數處理源碼解析
(4)#{}和${}傳參的區別
#{}:是預編譯的形式,將參數設置sql語句中,PreparedStatement,防sql注入。
${}:取出值直接拼裝在sql語句中;會有安全問題。
原生jdbc不支持佔位符的地方我們就是可以使用${}進行取值(如:動態的查表,動態獲取字段等)_。
參數中還有其他屬性的設置如:
javaType:以根據參數對象的類型確定 javaType jdbcType:如果一個列允許使用 null 值,並且會使用值爲 null 的參數,就必須要指定 JDBC 類型(jdbcType),比如有些數據庫可能不能識別mybatis對null的默認處理,比如我們的oracle。 jdbcType other:無效的類型,因爲mybatis對所有的null都映射的是原生JDBC的other
3、查詢sql映射解析
(1)、常用查詢方式
/***************查詢一個列表****************/
public List<OkrRole> getListByNameLike(String name);
對應map映射文件:
<select id="getListByNameLike" resultType="com.tan.bo.OkrRole">
select * from okr_role where id = #{id}
</select>
/***************返回一條記錄的map;key是列名,值就是對應的值****************/
public Map<String, Object> getOkrRoleByIdReturnMap(Integer id);
對應map映射文件:
<select id="getOkrRoleByIdReturnMap" resultType="map">
select * from okr_role where id = #{id}
</select>
/*多條記錄就封裝成一個map,Map<Integer, OkrRole>:鍵是這條記錄的主鍵,值是記錄封裝後的Java對象*/
@MapKey("id")
public Map<Integer, OkrRole> getgetOkrRoleByNameReturnMap(String name);
對應map映射文件:
<select id="getgetOkrRoleByNameReturnMap" resultType="com.tan.bo.OkrRole">
select * from okr_role where name LIKE #{name}
</select>
(2)、resultType:返回值類型
別名或者全類名,如果返回的是集合,定義集合中元素的類型,不能和resultMap同時使用。
(3)、resultMap:返回值類型
實例規則1:
<!--
自定義某個javabean的封裝規則
type:自定義貴則Java類型
id:唯一id方便引用
-->
<resultMap id="resultOkrRoleMap" type="com.tan.bo.OkrRole">
<!--
指定主鍵封裝規則
id:定義主鍵會底層有優化
column:指定哪一列
property:指定對應Javabean屬性
-->
<id column="id" property="id" />
<!--定義普通列封裝規則-->
<result column="last_name" property="lastName"/>
<!--其他不指定的列會自動封裝,我們只要寫resultMap就把全部的映射規則都寫上-->
<result column="email" property="email"/>
</resultMap>
實例規則2:
聯合查詢:級聯屬性封裝結果集
<!--如果OkrRole實體類有其他實體的屬性,就用以下級聯的方式去寫,dept就是OkrRole定義的別的實體的,deptName:在別的實體中-->
<result column="dept_name" property="dept.deptName"/>
實例規則3: 是對實例規則2的另外一種實現方式
association標籤也可以指定聯合Javabena的對象
<!--
association標籤也可以指定聯合Javabena的對象.
roperty="dept":指定哪個屬性是聯合的對象
javaType:指定這個屬性對象的類型(不能省略)
-->
<association property="dept" javaType="com.tan.bo.Dept">
<id column="did" property="id" />
<result column="dept_name" property="deptName"/>
</association>
實例規則4:利用association進行分步查詢:
/*******分步查詢步驟*******/
利用association進行分步查詢
1、先按照員工id查詢員工信息
2、根據查詢員工信息中關聯d_id值取部門表查詢部門信息
3、部門設置到員工中
/*******解析*******/
<association property="dept" select="com.tan.bo.Dept.getDeptById" column="d_id"/>
association:定義關聯對象的封裝規則
select:標明當前屬性是代用select指定的方法查出的結果
column:指定將哪一列的值傳給這個方法
實例5:使用延遲加載(按需加載,懶加載)
上面我們查詢員工的信息的時候,會將員工關聯的部門信息會一起查詢出來,現在我們要做的是,部門信息在我們去使用的時候在去查詢,這就是延遲加載,在分步查詢的基礎之上加上兩個配置就可以,如下實例:
/*******在mybatis全部配置文件中設置延遲加載*****/
<!--開啓延遲加載-->
<setting name="lazyLoadingEnabled" value="true" />
<!--侵入加載設置,如果這個地方爲true的話,在我們使用其中一個屬性的時候會將所有的屬性加載出來,如果是false的話使用哪個屬性就加載出哪個屬性-->
<setting name="aggressivelazyLoading" value="false" />
實例6:查詢某個部門下所有員工信息
collection嵌套結果集的方式,定義關聯的集合類型元素的封裝規則
第一步:寫一個連表查詢
第二步:
<!--
collection定義關聯集合類型的屬性的封裝規則
ofType:指定集合裏面原色的類型
-->
<collection property="okrRole" ofType="com.tan.bo.OkrRole">
<id column="okrRole_id" property="id" />
<result column="last_name" property="lastName"/>
</collection>
實例7:鑑別器
mybatis可以使用discriminator判斷某列的值,然後根據某列的值改變封裝的行爲
<!--
鑑別器:mybatis可以使用discriminator判斷某列的值,然後根據某列的值改變封裝的行爲
column:指定判斷的列
javaType:列值對應的Java類型
-->
<discriminator javaType="" column="gengder">
<!--女生 resultMap:指定封裝的結果類型-->
<case value="0" resultMap=""></case>
<!--男生 resultMap:指定封裝的結果類型-->
<case value="1" resultMap=""></case>
</discriminator>