目录
一、延迟加载
针对对高级查询结果的映射,结果映射必须使用ResultMap
1、什么是延迟加载?
按需加载,当要使用的时候在进行数据库的查询
2、策略
需要将已经写好的关联查询才分开,拆分成多个查询
3、开启延时加载
全局配置文件中
<setting name="lazyLoadingEnabled" value="true"></setting> --开启全局的延时加载
<setting anme="aggressiveLazyLoading" value="false"> </setting> --开启按需加载
4、一对一的延时加载
这是我们之前一对一的高级查询的sql语句,但是我们发现有的时候我们不需要用户的详细信息,但是还是查询出来了,存入了内存,这样就非常消耗内存,因此我们引入了延时加载--即当我们要看详细信息的时候,在进行查找
select a.* ,b.id detail_id,user_id,card_no,birthday,mobile,email
from b_user a
left join b_user_info b on a.id = b.user_id
延时加载
select * from b_user
需要查询某个用户的详细信息时
select * from b_user_info where id=?
代码
<!-- 1对1的延迟加载 -->
<resultMap id="map21" type="com.sofwin.dto.BUserDto">
<id column="id" property="id"/>
<result column="login_name" property="loginName"/>
<result column="pwd" property="pwd"/>
<result column="status" property="status"/>
<result column="create_date" property="createDate"/>
<result column="last_login_date" property="lastLoginDate"/>
<!--
association一对一的结果映射
select:映射文件中的一个查询的sqlId(不是一个映射文件也可以 nameSpace.sqlId)
注意的是:该sqlId的查询结果必须与 association的javaType一致
因为association是一个类,因此查询结果应该小于或者等于1
因为是条件查询需要传入参数, column:用于指定当前查询结果的那一列作为被调用的select的输入参数
上面的是id是一个的时候 当id是联合主键的时候
column={key=value(colunm),key2=value2}
被调用的输入参数的类型只能是pojo或者hashmap pojo:key key2是pojo的属性的属性名
map:key key2 为map中的key
-->
<associoation column="{id=id,status=status}" property="info" javaType="buserinfo" select="selectInfoByUserId" >
</association> </reusltMap>
<select id="selectInfoByUserId" parameterType="map" resultType="buserinfo">
select id,user_id userId,card_no cardNo,birthday,mobile,email
from b_user_info where user_id=#{id} or id=#{status}
</select>
5、一对多
<resultMap id="map31"
type="com.sofwin.dto.OrderMainDto">
<id column="id" property="id"/>
<result column="order_no" property="orderNo"/>
<result column="user_id" property="userId"/>
<result column="status" property="status"/>
<result column="total" property="total"/>
<!--
select: 被调用的查询返回结果应该是ofType类型的集合
-->
<collection property="details" ofType="orderdetail" select="selectDetailByMainId" column="id">
</collection>
</resultMap>
<select id="selectOrders2" resultMap="map31">
select * from b_ordermain
</select>
<select id="selectDetailByMainId" parameterType="int" resultType="orderdetail">
select id,main_id mainId,goods_id goodsId,price,num,total from b_orderdetail
where main_id=#{id}
</select>
二、二级缓存
1、缓存:
将原来磁盘中存储的数据,存放到内存中
2.mybatis的缓存原理
3.一级缓存
mybatis默认开启一级缓存。一级缓存是sqlSession级别的缓存,同一个sqlSession在调用相同的mapperstatement(sqlId一致,输入参数相同)时多次调用触发缓存
public static void main(String[] args) {
SqlSession session =SqlSessionUtil.getSession();
UserMapper mapper =session.getMapper(UserMapper.class);
List<BUserDto> info1 =mapper.selectUserInfo();
List<BUserDto> info2 =mapper.selectUserInfo();
// 执行insert语句
List<BUserDto> info3 =mapper.selectUserInfo();
}
//这样的同一个sqlSession调用相同的mapperStatement,只会第一次查询数据库一次,下一次就直接在内存中获取了
4.二级缓存
mybatis的二级缓存默认是关闭的,二级缓存是mapper级别的缓存,不同的sqlSession调用相同的mapperStatement时,多次嗲用触发缓存
二级缓存的开启条件
1.开启全局缓存开关
<setting name="cacheEnabled" value="true"></setting>
2.开启局部缓存开关(映射文件中)
<cache></cache>
3.查询结果的实体类必须是可序列化
4.不同的sqlSession必须出自同一个sqlSessionFactory
5.使用后的sqlSession必须关闭
public static void main(String[] args) {
SqlSession session =SqlSessionUtil.getSession();
UserMapper mapper =session.getMapper(UserMapper.class);
mapper.selectUsers(null);
session.close();
SqlSession session1 =SqlSessionUtil.getSession();
UserMapper mapper1 =session1.getMapper(UserMapper.class);
mapper1.selectUsers(null);
session1.close();
SqlSession session2 =SqlSessionUtil.getSession();
UserMapper mapper2 =session2.getMapper(UserMapper.class);
mapper2.selectUsers(null);
session2.close();
三、分页
采用插件的形式进行分页。plugins基于interceptor拦截器
mybatis使用的第三方插件---github开源的项目pageHelper
步骤:
1. 引入分页插件
pagehelper-x.y.z.jar and jsqlparser-x.y.z.jar
pagehelper分页的核心依赖。支持所有关系型数据库的分 页。
jsqlparse会根据不同的数据库方言将sql语句翻译成 对应的分页语句
注意:pagehelper-x.y.z.jar and jsqlparser-x.y.z.jar是有版本的对应关系的
2. 配置拦截器插件
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>
3.PageHelper.startPage 静态方法调用
除了 PageHelper.startPage 方法外,还提供了类似用 法的 PageHelper.offsetPage 方法。
在你需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟在这个方 法后的第一个MyBatis 查询方法会被进行分页。
4、代码
//分页 第一个参数 第几页 第二个参数每页显示的数据数
PageHelper.startPage(1, 5); //只有这个语句的紧跟着查询语句进行了分页
List<BUser> userlist = mapper.selectUser();
//将分页的数据封装到info中
PageInfo pageInfo=new PageInfo(userlist);
System.out.println("总数据量:"+pageInfo.getTotal());
System.out.println("当前页码:"+pageInfo.getPageNum());
System.out.println("每页的数量:"+pageInfo.getPageSize());
System.out.println("当前页的数量:"+pageInfo.getSize());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("前一页:"+pageInfo.getPrePage());
System.out.println("后一页:"+pageInfo.getNextPage());
System.out.println("是否为一页:"+pageInfo.isIsFirstPage());
System.out.println("是否为最后一页:"+pageInfo.isIsLastPage());
List list = pageInfo.getList();
System.out.println(list.size());
for (Object object : list) {
System.out.println((BUser)object);
}