MyBatis中的级联

作者: singworld 分类: MyBatis 发布时间: 2019-05-04 13:40

screenshot.jpeg

MyBatis中的级联分为3种

  1. 鉴别器(discriminator),根据某种条件决定具体采用具体实现类级联方案,比如体检表要根据性别区分
  2. 一对一(association) 一对一级联
  3. 一对多 (collection) 一对多关系
    值得注意的是MyBatis没有多对多级联,但可以通过两个一对多级联替换

一对一 一对多 鉴别器

POJO

private WorkCard workCard; //一对一
private List<EmployeeTask> employeeTaskList =null //一对多

配置文件

<resultMap type="com.xxx.yyy.pojo.EmployeeTask" id="EmployeeTaskMap">
    <id column ="id" property="id">
    <result column="emp_id" property="empId" />
    <result column="task_name" property="taskName" />
    <assocition property="task" columb="task_id" select ="com.xxx.yyy.taskMapper.getTask" />

    //一对多
    <collection property="employeeTaskList" column="id" select="com.xxx.yyy. employeeTaskMapper.getEmployeeTaskByEmpid">

    //鉴别器
    <discriminator javaType="long" column="sex">
        <case value="1" resultMao="maleHealthFormMapper">
        <case value="2" resultMao="femaleHealthFormMapper">
    </discriminator>
</resultMap>

<resultMap type="com.xxx.yyy.pojo.FemaleEmployee" id="femaleHealthFormMapper" extends="employee">
    <assocition property="femaleHealthForm" columb="id" select ="com.xxx.yyy.FemaleHealthFormMapper.getFemaleHealthForm" />

</resultMap>

延迟加载 解决N+1问题

在MyBatis多settings配置中存在两个元素可以配置级联
1. lazyLoadingEnabled 全局延迟加载 默认false
2. aggressiveLazyLoading 对任意属性调用延迟加载 3.41(包含)之前为true之后为false,控制是否采用层级加载
3. fetchType可以处理全局定义无法处理多问题,进行自定义,fetchType出现在级联元素(assocition ,collection ,鉴别器discriminator 没有这个属性) 存在两个值
1. eager 获得当前pojo后立即加载对应数据,
2. lazy获得当前pojo后延迟加载对应数据
在保证lazyLoadingEnabled =true 和 aggressiveLazyLoading =false的前提下

    //一对多
    <collection property="employeeTaskList" column="id" fetch="eager"  select="com.xxx.yyy. employeeTaskMapper.getEmployeeTaskByEmpid">

多对多级联

<resultMap type="com.xxx.yyy.pojo.Role2" id="roleMapper">
    <id column="id" property="id" />
    <result column="role_name" property="roleName" />

    <collection property="userList" column="id" 
    fetch="lazy" select="com.xxx.yyy. UserMapper2.findUserRoleId">
</resultMap>
<select id ="getRole" parameterType="long" resultMap="roleMap">
    select xxxx
</select>


<select id ="findRoleByUserId" parameterType="long" resultMap="roleMap">
    select xxxx where r.id=ur.role_id and r.user_id=#{userId}
</select>

缓存

一级缓存默认开启
开启二级缓存,只要在映射文件(xxxMapper.xml)上加上代码\ pojo实现序列化接口

缓存配置项,自定义和引用

在现实中可以使用Readis等NOSQL常用缓存

<cache type = "com.xxx.yyy.ReadisCache">
    <property name="host" value="localhost">
</cache>

这样配置后MyBatis会启用缓存,同时调用setHost(String host)方法设置内容,对于一些查询并不想它进行缓存,可以配置如下

<select xxx flushCache="False" useCache="true">
<insert xxx  flushCache="False" / >
<update xxx  flushCache="False" / >
<delete xxx  flushCache="False" / >
  1. flushCache代表是否刷新缓存
  2. useCache是select特有等,代表是否需要使用缓存
    其他映射器可以通过如下引用
    <cache-ref namespace="com.xxx.yyy.mapper.RoleMapper" />

存储过程

<select id="countRole" parameterType="com.xxx.yyy.PdcountRoleParams" statementType="CALLABLE">
{call count_role(
    #{roleName, mode=IN, jdbcType="VARCHAR"}
    #{total, mode=OUT, jdbcType="INTEGER"}
    #{execDate, mode=OUT, jdbcType="DATE"}
)}
</select>

游标的使用

<select id="countRole" parameterType="com.xxx.yyy.PdcountRoleParams" statementType="CALLABLE">
{call count_role(
    #{roleName, mode=IN, jdbcType="VARCHAR"}
    #{total, mode=OUT, jdbcType="INTEGER"}
    #{execDate, mode=OUT, jdbcType="DATE"}
    #{roleList, mode=OUT, jdbcType="CURSOR" javaType="ResultSet",resultMap="roleMap"}
)}
</select>

Leave a Reply

Your email address will not be published. Required fields are marked *