概述
- 我们已经知道mybatis中的一对一,一对多,多对多关系的配置及实现,可以实现对象的关联查询。实际开发过程中,我们并不需要加载用户信息时,就加载它的账户信息,而是在使用用户账号的时候,再向数据库查询,此时就是我们所说的延迟加载
什么是延迟加载
- 就是在需要用到数据的时候才进行加载,不需要用到数据的时候就不加载数据。延迟加载也称为懒加载
- 优点:先从单表查询,需要时再从关联表去关联查询,大大提高数据库的性能,因为查询单表要比关联查询多张表的速度快很多
- 缺点:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也需要耗费时间,所以可能造成用户等待时间变长,造成用户体验下降
实现
商品表Items
public class Items {
//货物编号
private int iid;
//货物名称
private String name;
//货物详情
private String detail;
//货物价格
private double price;
public Items() {
}
public Items(int iid, String name, String detail, double price) {
this.iid = iid;
this.name = name;
this.detail = detail;
this.price = price;
}、
...
}
订单详情表OrderDetail
public class OrderDetail {
//主键
private int odid;
//订单编号
private int orderid;
//货物数量
private int itemnum;
//商品对象
private Items items;
public OrderDetail() {
}
public OrderDetail(int odid, int orderid, int itemnum, Items items) {
this.odid = odid;
this.orderid = orderid;
this.itemnum = itemnum;
this.items = items;
}
...
}
ItemsMapper.java
public interface ItemsMapper {
//根据主键查询Items对象
Items selectByiid(int iid) throws Exception;
}
OrderDetailMapper.java
public interface OrderDetailMapper {
//通过主键查询OrderDetail对象
OrderDetail selectByOdid(int odid) throws Exception;
}
ItemsMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.msb.mapper.ItemsMapper">
<select id="selectByiid" parameterType="int" resultType="items">
select * from Items where iid = #{id}
</select>
</mapper>
OrderDetailMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.msb.mapper.OrderDetailMapper">
<resultMap id="findItem" type="com.msb.pojo.OrderDetail">
<id property="odid" column="odid"></id>
<result property="orderid" column="orderid"></result>
<result property="itemnum" column="itemnum"></result>
<!--延迟加载中select:表示查询语句是谁,这里就是另一个映射文件的sql id,写法是:对应mapper文件的namespace.id-->
<!--column:表示针对的列名是谁,这里就是两张表关联的外键-->
<association property="items" javaType="com.msb.pojo.Items"
select="com.msb.mapper.ItemsMapper.selectByiid" column="itemid"></association>
</resultMap>
<select id="selectByOdid" parameterType="int" resultMap="findItem">
select * from OrderDetail where odid = #{id}
</select>
</mapper>
测试类
public class MabatisTest {
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
initLogRecord.initLog();
InputStream resource = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(resource);
}
@Test
public void test() throws Exception {
SqlSession sqlSession = factory.openSession();
OrderDetailMapper mapper = sqlSession.getMapper(OrderDetailMapper.class);
//根据主键id查单个对象
OrderDetail orderDetail = mapper.selectByOdid(1);
//获取订单详情自己的属性
System.out.println("订单详情表中Orderid的值:"+orderDetail.getOrderid());
//获取订单详情关联订单中订单价格属性
System.out.println("订单详情表中关联订单的价格:"+orderDetail.getItems().getPrice());
}
}
情况一
SqlMapperConfig.xml
<settings>
<!--延迟加载总开关,true为开启,false为关闭-->
<setting name="lazyLoadingEnabled" value="false"/>
<!--积极懒加载和消极懒加载开关,false为消极懒加载,true为积极懒加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
- 运行OrderDetail orderDetail = mapper.selectByOdid(1)时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条)
- 运行orderDetail.getOrderid()时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条)
- 运行orderDetail.getItems().getPrice()时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条)
情况二
SqlMapperConfig.xml
<settings>
<!--延迟加载总开关,true为开启,false为关闭-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--积极懒加载和消极懒加载开关,false为消极懒加载,true为积极懒加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
- 运行OrderDetail orderDetail = mapper.selectByOdid(1)时,sql执行了:select * from OrderDetail where odid = ? (一条)
- 运行orderDetail.getOrderid()时,sql执行了:select * from OrderDetail where odid = ? (一条)
- 运行orderDetail.getItems().getPrice()时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条),使用到关联对象属性的时候才加载对应sql
情况三
SqlMapperConfig.xml
<settings>
<!--延迟加载总开关,true为开启,false为关闭-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--积极懒加载和消极懒加载开关,false为消极懒加载,true为积极懒加载-->
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
- 运行OrderDetail orderDetail = mapper.selectByOdid(1)时,sql执行了:select * from OrderDetail where odid = ? (一条)
- 运行orderDetail.getOrderid()时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条),Items也是OrderDetail类下的属性所以被加载
- 运行orderDetail.getItems().getPrice()时,sql执行了:select * from OrderDetail where odid = ? 和 select * from Items where iid = ?(两条)