对于一些数据比较庞大的web管理系统中,如果是一次性的把所有数据查询出来,必然会给数据库带来压力,可能会导致数据库崩溃,这个时候就不得不优化该系统了,针对这些问题的处理方法,最为常见的是缓存或者其他方法,在这里要讲述的是mybatis的延迟加载,虽然这个方法不能从根本上解决问题,但是对于也可以达到优化系统的效果。
那么,什么叫延迟加载呢?延迟加载通俗来说就是首次查询只查询主要信息,关联信息等用户获取时再加载。即按需加载,需要时才去数据库查询,从而有效的减少数据库压力。
- 首先,要使用mybatis中的延迟加载,就必须在mybatis的配置文件中设置以下两个属性:
设置项 描述 默认值
lazyLoadingEnabled 全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。 false
aggressiveLazyLoading 当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 true
在mybatis配置文件中添加如下信息:
<!--开启二级缓存 注意配置顺序 settings在前面 -->
<settings>
<setting name="lazyLoadingEnabled" value="true" />
<setting name="aggressiveLazyLoading" value="false" />
</settings>
- 创建相关的pojo类UUserRole,该类继承了UUser类的信息,在里面创建List属性,这里是一对多的关系(一个用户对于多个角色):
public class UUserRole extends UUser implements Serializable {
private static final long serialVersionUID = 2400605027010626685L;
private List<URole> role;
public List<URole> getRole() {
return role;
}
public void setRole(List<URole> role) {
this.role = role;
}
}
- 在mapper映射编写相关sql语句
首先把用户的主要信息查询出来,当需要查询相关的角色时,再通过用户的ID来查询该用户拥有的角色,这样就可以到达延迟效果。
<!-- 查询用户列表 -->
<select id="selectRoleAllocation" parameterType="string"
resultMap="user" >
SELECT u_user.id user_id, u_user.nickname user_nickname,u_user.email
user_email,u_user.status user_status FROM u_user
<if test="info!=''">
<where>
AND (u_user.nickname like concat('%',#{info},'%')
OR
u_user.email like concat('%',#{info},'%'))
</where>
</if>
</select>
<!-- 返回用户列表和嵌套查询该用户的所拥有的角色 -->
<resultMap type="UUserRole" id="user">
<id column="user_id" property="id" />
<result column="user_nickname" property="nickname" />
<result column="user_email" property="email" />
<result column="user_status" property="status" />
<collection property="role" ofType="URole" column="user_id" select="queryRoleByUserId">
</collection>
</resultMap>
<!-- 通过用户id查询角色列表 -->
<select id="queryRoleByUserId" resultType="URole">
SELECT
u_role.id,u_role.name,u_role.type FROM u_role
LEFT
JOIN u_user_role ON
u_role.id=u_user_role.rid
WHERE
u_user_role.uid=#{user_id}
</select>
测试代码如下:
@Override
public ResuleVo selectRoleAllocation(String info,Integer page,Integer limit) {
PageHelper.startPage(page, limit, true);
List<UUserRole> list = userRoleMapper.selectRoleAllocation(info);
PageInfo<UUserRole> pageInfo=new PageInfo<UUserRole>(list);
long count=pageInfo.getTotal();
for (UUserRole uUserRole : list) {
uUserRole.setRole(uUserRole.getRole());
}
return ResuleVo.toLayui(count, list);
}
其实mybatis的延迟加载就分两步来执行sql语句,首先把主要信息查询出来,然后再通过关联的id来查询关联表,所以说,即是没有mybatis的延迟加载也可以到达这种延迟的效果,只不过是分了两种方法来执行对应的sql语句而已。