Mybatis 延迟加载策略
延迟加载:
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
好处:
先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速 度要快。
坏处:
因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗 时间,所以可能造成用户等待时间变长,造成用户体验下降。
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常情况下我们都是采用延迟加载。
多对一,一对一:通常情况下我们都是采用立即加载。
使用 assocation 实现延迟加载
需求:
查询账户(Account)信息并且关联查询用户(User)信息。如果先查询账户(Account)信息即可满足要求,当我们需要查询用户(User)信息时再查询用户(User)信息。
用户(User)信息按需查询
账户的持久层映射文件 :
在association标签中
select 填写要调用的select映射的ID
column 填写要传递给select映射的参数
<mapper namespace="com.mkl.dao.IAccountDao"> <!--定义封装account和user的resultMap--> <resultMap id="accountUserMap" type="account"> <id column="id" property="id"></id> <result column="uid" property="uid"></result> <result column="money" property="money"></result> <!--一对一的关系映射, 配置封装User的内容--> <!--<association property="user" javaType="user">--> <!--<id column="id" property="id"></id>--> <!--<result column="username" property="username"></result>--> <!--<result column="sex" property="sex"></result>--> <!--<result column="birthday" property="birthday"></result>--> <!--<result column="address" property="address"></result>--> <!--</association>--> <association property="user" javaType="user" select="com.mkl.dao.IUserDao.findUserById" column="uid"></association> <!--select 填写要调用的select映射的ID column 填写要传递给select映射的参数 --> </resultMap> <!-- 查询所有账户信息--> <select id="findAll" resultMap="accountUserMap"> select * from account </select> </mapper>
用户的持久层映射文件中添加
<!-- 根据id查询用户 --> <select id="findUserById" parameterType="int" resultType="user"> select * from user where id = #{uid} </select>
开启 Mybatis 的延迟加载策略 :
在 Mybatis 的配置文件 SqlMapConfig.xml 文件中添加延迟加载的配置
<!-- 开启延迟加载的支持 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/>
</settings>
使用 Collection 实现延迟加载
需求:
加载用户对象时,按需查询该用户所拥有的账户信息。
编写用户持久层映射配置 :
<mapper namespace="com.mkl.dao.IUserDao"> <resultMap id="userMap" type="user"> <id column="id" property="id"></id> <result column="username" property="username"/> <result column="address" property="address"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <!--封装该用户下的账户信息到List--> <!--collection是用于建立一对多中集合属性的对应关系, ofType用于指定集合元素的数据类型--> <!--<collection property="accounts" ofType="account">--> <!--<id column="aid" property="id"/>--> <!--<result column="uid" property="uid"/>--> <!--<result column="money" property="money"/>--> <!--</collection>--> <collection property="accounts" ofType="account" select="com.mkl.dao.IAccountDao.findByUid" column="id"></collection> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="userMap"> SELECT * FROM USER </select> <!-- 根据id查询用户 --> <select id="findUserById" parameterType="int" resultType="user"> select * from user where id = #{uid} </select> </mapper>
select 属性:
用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id
column 属性:
用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,所以就写成 id 这一 个字段名了
在账户持久层映射配置文件中添加:
<!-- 根据用户 id 查询账户信息 -->
<select id="findByUid" resultType="account" parameterType="int">
select * from account where uid = #{uid}
</select>