Mybatis–延迟加载
MyBatis中的延迟加载,也称为懒加载,是指在进行表的关联查询时,按照设置延迟规则推迟对关联对象的select查询。例如在进行一对多查询的时候,只查询出一方,当程序中需要多方的数据时,mybatis再发出sql语句进行查询,这样子延迟加载就可以的减少数据库压力。MyBatis 的延迟加载只是对关联对象的查询有迟延设置,对于主加载对象都是直接执行查询语句的。
一对多,多对多:一般采用延迟加载
多对一,一对一:一般采用立即加载
assosiation标签–延迟加载使用方式(以一对一(多对一)为例)
account表
user表
一个用户可以有多个账号,而一个账号只能对应一个用户,一次账号对应用户是一对一关系或多对一关系。
如果不使用延迟加载,代码详见链接: link.
使用延迟加载步骤:
1.在AccountMapper下定义方法findAccountUser();
List<Account> findAccountUser();
2.AccountMapper.xml下配置
<resultMap id="AccountUserMap" type="com.ouc.a302.pojo.Account" >
<id column="id" property="aid" jdbcType="INTEGER" />
<result column="accountdesc" property="accountdesc" jdbcType="VARCHAR" />
<result column="userid" property="userid" jdbcType="INTEGER" />
<association column="id" property="user" javaType="com.ouc.a302.pojo.User" select="com.ouc.a302.dao.UserMapper.findUser"></association>
</resultMap>
<select id="findAccountUser" resultMap="AccountUserMap">
select * from account;
</select>
3.UserMapper下定义方法findUser();
User findUser(int uid);
4.UserMapper.xml下配置
<resultMap id="usermap" type="com.ouc.a302.pojo.User" >
<id column="id" property="uid" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="userage" property="userage" jdbcType="INTEGER" />
<result column="usergender" property="usergender" jdbcType="VARCHAR" />
<result column="usercountry" property="usercountry" jdbcType="VARCHAR" />
</resultMap>
<select id="findUser" resultMap="usermap" parameterType="Integer">
select * from user where id=#{uid}</select>
5.SqlMapConfig.xml文件中开启延迟加载
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
ps:标签一定写下前面
6.运行
1.情况一,输出语句中不包含user表中的内容
List<Account> accountUser1 = accountMapper.findAccountUser();
for (Account account : accountUser1) {
System.out.println("accountdesc = " + account.getAccountdesc());
}
日志显示只有select * from account被执行了,而usermapper中的select * from user where id=#{uid}没执行。
2.情况二,输出语句中包含user表中的内容
List<Account> accountUser1 = accountMapper.findAccountUser();
for (Account account : accountUser1) {
System.out.println("user = " + account.getUser());
}
日志显示先执行了select * from account,后执行了select * from user where id=#{uid}。
根据如上两种情况,可以得出结论,当使用了延迟加载后,List accountUser1 = accountMapper.findAccountUser();执行时,如果没有使用account类中的user则user对应的sql语句不会执行,如果执行时使用了account类中的user,如
List accountUser1 = accountMapper.findAccountUser(); 则会user对应的sql语句会执行。
这就是延迟加载里的按需执行sql语句,只有在需要的时候才会去执行。
collection标签–延迟加载使用方式(以一对多 为例)
user类
一对多查询时,user类为主表,user类中包换account的集合。
account类
使用延迟加载步骤:
1.在UserMapper下定义方法findUserAccount();
List<User> findUserAccount();
2.UserMapper.xml下配置
<resultMap id="usermap" type="com.ouc.a302.pojo.User" >
<id column="id" property="uid" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="userage" property="userage" jdbcType="INTEGER" />
<result column="usergender" property="usergender" jdbcType="VARCHAR" />
<result column="usercountry" property="usercountry" jdbcType="VARCHAR" />
<collection column="id" property="accounts" ofType="com.ouc.a302.pojo.Account" select="com.ouc.a302.dao.AccountMapper.findAccount"></collection>
</resultMap>
<select id="findUserAccount" resultMap="usermap">
select * from user
</select>
3.AccountMapper下定义方法findAccount();
List<Account> findAccount(int aid);
4.AccountMapper.xml下配置
<resultMap id="AccountMap" type="com.ouc.a302.pojo.Account">
<id column="id" property="aid" jdbcType="INTEGER"/>
<result column="accountdesc" property="accountdesc" jdbcType="VARCHAR"/>
<result column="userid" property="userid" jdbcType="INTEGER"/>
</resultMap>
<select id="findAccount" resultMap="AccountMap" parameterType="Integer">
select * from account where id=#{aid}
</select>
5.SqlMapConfig.xml文件中开启延迟加载
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"></setting>
</settings>
ps:标签一定写下前面
6.运行
1.情况一,输出语句中不包含account表中的内容
List<User> userAccount = userMapper.findUserAccount();
for (User user : userAccount) {
System.out.println("username = " + user.getUsername());
}
2.情况二,输出语句中包含account表中的内容
List<User> userAccount = userMapper.findUserAccount();
for (User user : userAccount) {
System.out.println("accounts= " + user.getAccounts());
}