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>

 

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