mybatis中的resultMap元素和级联

Mybaits中的级联分为三种:
        鉴别器:根据某些条件决定采用具体的实现方案
  一对一:比如学生和学生证
       一对多:比如班主任和学生
鉴别器配置:


    <select id="getRoleByDiscriminator" parameterType="int" resultMap="discriminator">
         select id,role_name ,note as note_ from t_role where id = #{id}
    </select>
    <resultMap id="discriminator" type="pojo.Role" >
        <discriminator javaType="string" column="role_name">
            <case value="小红" resultMap="resultMap1"></case>
            <case value="小明" resultMap="resultMap2"></case>
        </discriminator>
    </resultMap>

    <resultMap id="resultMap1" type="pojo.Role">
        <id property="id" column="id"></id>
        <result property="roleName" column="role_name"></result>
        <result property="note" column="note_"></result>
    </resultMap>
    <resultMap id="resultMap2" type="pojo.Role">
        <id property="id" column="id"></id>
        <result property="roleName" column="role_name"></result>
    </resultMap>

测试程序:

public class test {
    public static void main(String[] args) throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        RoleMapper mapper = sqlSession.getMapper(RoleMapper.class);
        Role roleByDiscriminator = mapper.getRoleByDiscriminator(5);
        System.out.println(roleByDiscriminator.toString());
        Role roleByDiscriminator1 = mapper.getRoleByDiscriminator(6);
        System.out.println(roleByDiscriminator1.toString());
        RowBounds rowBounds = new RowBounds(0,2);
        List<Role> rolesByrowBounds = mapper.getRolesByrowBounds(rowBounds);
        System.out.println(rolesByrowBounds.size());
        sqlSession.close();
    }
}

测试结果

一对一级联配置:

<select id="getRoleAndUser1" parameterType="int" resultMap="getRoleByCascade1">
        select  id ,role_name as roleName ,note from t_role where id = #{id}
    </select>
    <resultMap id="getRoleByCascade1" type="pojo.Role">
        <id property="id" column="id"></id>
        <result property="roleName" column="roleName"></result>
        <association property="user" column="id" javaType="mytyperhandler.User" select="mytyperhandler.UserMapper.selectOne"></association>
    </resultMap>

这里要注意一下:association中的column对应的是t_role表中的属性,即以该属性为条件查询对应的user,响应的如果不在resultMap中配置作为依据的列,那么其值就为默认值,所以如果需要要配置,这里的id配置了,所以可以取到id,否则将取到默认值0

测试代码:


public class test {
    public static void main(String[] args) throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        RoleMapper mapper = sqlSession.getMapper(RoleMapper.class);
        Role roleByDiscriminator = mapper.getRoleAndUser1(1);
        System.out.println(roleByDiscriminator.getId());
        System.out.println(roleByDiscriminator.getNote());
        System.out.println(roleByDiscriminator.getRoleName());
        System.out.println(roleByDiscriminator.getUser().getAge());

        sqlSession.close();
    }
}

一对多级联配置:

 <resultMap id="getUser" type="user">
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
        <result property="hobbys" column="hobbys" typeHandler="mytyperhandler.StringArrayByBaseTyperHandler"></result>
    </resultMap>

    <select id="selectOneByName" parameterType="string" resultMap="getUser">
        select name,age,hobbys from users where name = #{name}
    </select>

 <select id="getRoleAndUsers" parameterType="int" resultMap="getRoleByCascade2">
        select  id ,role_name as roleName ,note from t_role where id = #{id}
    </select>
    <resultMap id="getRoleByCascade2" type="pojo.Role">
        <id property="id" column="id"></id>
        <result property="roleName" column="roleName"></result>
        <collection property="users" column="roleName" select="mytyperhandler.UserMapper.selectOneUserByName"></collection>
    </resultMap>

Role结构:

public class Role {
    private int id;
    private String roleName;
    private String note;
    private User user;
    private List<User> users;

    setter/getter....
}

测试:

public class test {
    public static void main(String[] args) throws IOException {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        RoleMapper mapper = sqlSession.getMapper(RoleMapper.class);
        Role roleByDiscriminator = mapper.getRoleAndUsers(1);
        System.out.println(roleByDiscriminator.getId());
        System.out.println(roleByDiscriminator.getNote());
        System.out.println(roleByDiscriminator.getRoleName());
        System.out.println(roleByDiscriminator.getUsers().size());

        sqlSession.close();
    }
}

N+1问题:如果现在有N个关联关系完成了级联,那么只要再加入一个关联关系,就变成了N+1个级联,所有的级联sql都被执行,当我们需要的数据不那么多的时候,就会浪费性能
解决方案:使用延迟加载

当第一个参数设置为true时,就会将将所有的关联数据都查出来,设为true时,只会查出当前sql的数据,至于关联数据则不会查询,当调用关联数据的时候就会再次查询

一级缓存和二级缓存问题:
一级缓存就是对同一个对象进行两次获取,那么sql就执行一次,对于不同的SqlSession,需要一个执行了commit操作才会开启一级缓存,一级缓存实在SqlSession层面的
 

猜你喜欢

转载自blog.csdn.net/q1937915896/article/details/88086481