延迟加载

resultMap可以实现高级映射(使用association、collection实现一对一以及一对多映射),association、collection具备延迟加载功能。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能。

开启延迟加载需要在SqlMapConfig.xml的setting中设置

1
2
3
4
5
6
<settings>
<!-- 打开延迟加载 的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载即按需要加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

书写需要的两个satatement

  • 查询用户
1
2
3
4
5
<select id="findUserLazy" resultMap="findUserAndCarLazyMap">
SELECT *
FROM user
WHERE id = #{id}
</select>
  • 查询拥有的Car

    1
    2
    3
    4
    5
    <select id="findCarByUserId" parameterType="int" resultType="pojo.Car">
    SELECT *
    FROM car
    WHERE user_id = #{value}
    </select>
  • 书写resultMap

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <resultMap id="findUserAndCarLazyMap" type="pojo.User">
    <id property="id" column="id"></id>
    <result property="name" column="name"></result>
    <result property="password" column="password"></result>
    <!--
    多了select和column
    select:会去寻找相应的方法,如果不在本mapper中则需要在前面添加其namespace(我这里是放在本mapper中的)
    column:根据哪一列去进行查询。
    -->
    <association property="car"
    select="findCarByUserId"
    column="id"
    javaType="pojo.Car">

    </association>
    </resultMap>
  • 在相应的Mapper接口中书写方法

    1
    public User findUserLazy(int id);
  • 测试代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Test
    public void testFindUserLazyLoding(){
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    User user = userMapper.findUserLazy(2);
    System.out.println(user);

    //System.out.println(user.getCar().toString());
    }

PS:这里不知道是我用的IDEA的问题还是怎么的,在输出的时候竟然也执行了第二条sql语句。。。
http://ocx5m3vc3.bkt.clouddn.com/mybatis%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BDdebug.png

延迟加载debug

http://ocx5m3vc3.bkt.clouddn.com/mybatis%E4%B8%8D%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BDdebug.png
不延迟加载debug

更新:后来发现出现上面第一图的情况是由于在System.out.println(user);会执行第二条SQL。。 需要配置一下设置

1
<setting     name="lazyLoadTriggerMethods" value=" " />

lazyLoadTriggerMethods默认情况下仅仅支持自动将equals,clone,hashCode,toString这几个方法定义为延迟加载的加载触发方法。