Mybatis Map映射文件解析

一、映射文件解析

  1. 獲取自增主鍵的值
  2. 參數處理封裝
  3. 查詢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)、參數處理源碼解析

https://blog.csdn.net/kwy15732621629/article/details/79710346?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159133213919724845045152%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159133213919724845045152&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_blog_default-1-79710346.pc_v2_rank_blog_default&utm_term=mybatis%E4%BC%A0%E5%8F%82%E5%8E%9F%E7%90%86

(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>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章