03 高级映射 延迟加载

复习:
课程复习:

mybatis是什么?
mybatis是一人持久层框架,mybatis是一个不完全的ORM框架。sql语句需要程序员自己去编写,但是mybatis也有映射(输入参数映射、输出结果映射)。
mybatis入门门槛不高,学习成本低,让程序员把精力放在sql语句上,对sql语句优化非常方便,适用与需求变化较多项目,比如互联网项目。

mybatis框架执行过程:
1、配置mybatis的配置文件,SqlMapConfig.xml(名称不固定)
2、通过配置文件,加载mybatis运行环境,创建SqlSessionFactory会话工厂
SqlSessionFactory在实际使用时按单例方式。
3、通过SqlSessionFactory创建SqlSession
SqlSession是一个面向用户接口(提供操作数据库方法),实现对象是线程不安全的,建议sqlSession应用场合在方法体内。
4、调用sqlSession的方法去操作数据。
如果需要提交事务,需要执行SqlSession的commit()方法。
5、释放资源,关闭SqlSession

mybatis开发dao的方法:
1、原始dao 的方法
需要程序员编写dao接口和实现类
需要在dao实现类中注入一个SqlSessionFactory工厂。

2、mapper代理开发方法(建议使用)
只需要程序员编写mapper接口(就是dao接口)
程序员在编写mapper.xml(映射文件)和mapper.java需要遵循一个开发规范:
1、mapper.xml中namespace就是mapper.java的类全路径。
2、mapper.xml中statement的id和mapper.java中方法名一致。
3、mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入 参数类型一致。
4、mapper.xml中statement的resultType指定输出结果的类型和mapper.java的方法返回值类型一致。

SqlMapConfig.xml配置文件:可以配置properties属性、别名、mapper加载。。。

输入映射:
parameterType:指定输入参数类型可以简单类型、pojo、hashmap。。
对于综合查询,建议parameterType使用包装的pojo,有利于系统 扩展。

输出映射:
resultType:
查询到的列名和resultType指定的pojo的属性名一致,才能映射成功。
reusltMap:
可以通过resultMap 完成一些高级映射。
如果查询到的列名和映射的pojo的属性名不一致时,通过resultMap设置列名和属性名之间的对应关系(映射关系)。可以完成映射。
高级映射:
将关联查询的列映射到一个pojo属性中。(一对一)
将关联查询的列映射到一个List<pojo>中。(一对多)

动态sql:(重点)
if判断(掌握)
where
foreach
sql片段(掌握)

课程安排:
对订单商品数据模型进行分析。
高级映射:(了解)
实现一对一查询、一对多、多对多查询。
延迟加载
查询缓存
一级缓存
二级缓存(了解mybatis二级缓存使用场景)
mybatis和spirng整合(掌握)
逆向工程(会用)

订单商品数据模型

分析思路

1、每张表记录的数据内容
分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程。
2、每张表重要的字段设置
非空字段、外键字段
3、数据库级别表与表之间的关系
外键关系
4、表与表之间的业务关系
在分析表与表之间的业务关系时一定要建立 在某个业务意义基础上去分析。

  1. 数据模型分析思路
    1、每张表记录的数据内容
    分模块对每张表记录的内容进行熟悉,相当于你学习系统需求(功能)的过程。
    2、每张表重要的字段设置
    非空字段、外键字段
    3、数据库级别表与表之间的关系
    外键关系
    4、表与表之间的业务关系
    在分析表与表之间的业务关系时一定要建立 在某个业务意义基础上去分析。

  2. 数据模型分析


    用户表user:
    记录了购买商品的用户信息

订单表:orders
记录了用户所创建的订单(购买商品的订单)

订单明细表:orderdetail:
记录了订单的详细信息即购买商品的信息

商品表:items
记录了商品信息

表与表之间的业务关系:
在分析表与表之间的业务关系时需要建立 在某个业务意义基础上去分析。
先分析数据级别之间有关系的表之间的业务关系:

usre和orders:
user---->orders:一个用户可以创建多个订单,一对多
orders--->user:一个订单只由一个用户创建,一对一

orders和orderdetail:
orders---》orderdetail:一个订单可以包括 多个订单明细,因为一个订单可以购买多个商品,每个商品的购买信息在orderdetail记录,一对多关系

orderdetail--> orders:一个订单明细只能包括在一个订单中,一对一

orderdetail和itesm:
orderdetail---》itesms:一个订单明细只对应一个商品信息,一对一

items--> orderdetail:一个商品可以包括在多个订单明细 ,一对多

再分析数据库级别没有关系的表之间是否有业务关系:
orders和items:
orders和items之间可以通过orderdetail表建立 关系。

一对一查询

  1. 需求
    查询订单信息,关联查询创建订单的用户信息

  2. resultType

  • sql语句
    确定查询的主表:订单表
    确定查询的关联表:用户表
    关联查询使用内链接?还是外链接?
    由于orders表中有一个外键(user_id),通过外键关联查询用户表只能查询出一条记录,可以使用内链接。
    SELECT
    orders.*,
    USER.username,
    USER.sex,
    USER.address
    FROM
    orders,
    USER
    WHERE orders.user_id = user.id

  • 创建pojo
    将上边sql查询的结果映射到pojo中,pojo中必须包括所有查询列名。
    原始的Orders.java不能映射全部字段,需要新创建的pojo。
    创建 一个pojo继承包括查询字段较多的po类。

OrdersCustom.java

package cn.itcast.mybatis.po;


/*
 * 订单的扩展类
 * 
 * 通过此类映射订单和用户查询的结果,让此类继承较多的pojo类
 * */
public class OrdersCustom extends Orders{

    //添加用户属性信息
    private String Username;
    private String sex;
    private String address;
    /**
     * @return username
     */
    public String getUsername() {
        return Username;
    }
    /**
     * @return sex
     */
    public String getSex() {
        return sex;
    }
    /**
     * @return address
     */
    public String getAddress() {
        return address;
    }
    /**
     * @param username 要设置的 username
     */
    public void setUsername(String username) {
        Username = username;
    }
    /**
     * @param sex 要设置的 sex
     */
    public void setSex(String sex) {
        this.sex = sex;
    }
    /**
     * @param address 要设置的 address
     */
    public void setAddress(String address) {
        this.address = address;
    }
    
    
}

  1. mapper.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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
    注意,使用mapper代理开发,namespace有特殊重要的作用
 -->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">

    <!-- 查询订单关联查询用户 -->
    <select id="findOrdersUser" resultType="cn.itcast.mybatis.po.OrdersCustom">
        SELECT
        orders.*,
        USER.username,
        USER.sex,
        USER.address
        FROM
        orders,
        USER
        WHERE orders.user_id = user.id
    </select>
</mapper>

  • mapper.java
package cn.itcast.mybatis.mapper;

import java.util.List;

import cn.itcast.mybatis.po.OrdersCustom;
import cn.itcast.mybatis.po.User;
import cn.itcast.mybatis.po.UserCustom;
import cn.itcast.mybatis.po.UserQueryVo;

/*
 * 订单mappera
 * */
public interface OrdersMapperCustom {
    //查询订单关联查询用户信息
    public List<OrdersCustom> findOrdersUser() throws Exception;
}

  • 测试代码
    OrdersMapperCustomTest.java
package cn.itcast.mybatis.mapper;

import static org.junit.Assert.*;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import cn.itcast.mybatis.po.OrdersCustom;

public class OrdersMapperCustomTest {

    private SqlSessionFactory sqlSessionFactory;
    
    @Before
    public void setUp() throws Exception{
        //创建sqlSessionFactory
        
        
        //mybatis配置文件
        String resource = "SqlMapConfig.xml";
                
        //得到配置问价流
        InputStream inputStream = Resources.getResourceAsStream(resource);
                
        //创建会话工厂,传入mybatis的配置文件信息
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    
    @Test
    public void testFindOrdersUser() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        
        //调用mapper的方法
        List<OrdersCustom> list = ordersMapperCustom.findOrdersUser();
        
        System.out.println(list);
        
        sqlSession.close();
    }

}

resultMap

  1. 使用resultMap映射的思路
    使用resultMap将查询结果中的订单信息映射到Orders对象中,在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。

  2. 需要Orders类中添加user属性
    Orders.java

//用户信息
    private User user;

    /**
     * @return user
     */
    public User getUser() {
        return user;
    }

    /**
     * @param user 要设置的 user
     */
    public void setUser(User user) {
        this.user = user;
    }
  1. mapper.xml
  • 定义resultMap
<?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">

<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
    注意,使用mapper代理开发,namespace有特殊重要的作用
 -->
<mapper namespace="cn.itcast.mybatis.mapper.OrdersMapperCustom">

    <!-- 订单查询关联用户的resultMap
        将整个查询的结果映射到Orders中
     -->
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">
        <!-- 配置要映射的订单信息 -->
        <!-- id指定查询列中的唯一标识,是订单信息中的唯一标识,如果多个列组成唯一标识,配置多个id 
            column:订单信息的唯一标识列
            property:订单信息的唯一标识列所映射到Orders中哪个属性
        -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 配置映射的关联的用户信息 -->
        <!-- 用于映射管关联查询单个对象的信息 
            property:要将关联查询的用户信息映射到Orders中哪个属性
        -->
        <association property="user" javaType="cn.itcast.mybatis.po.User">
            <!-- id:关联查询用户的唯一标识
                column:指定唯一标识用户信息的列
                javaType:映射到User的哪个属性
             -->
             <id column="user_id" property="id"/>
             <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
            
            
        </association>
        
    </resultMap>

  • statement定义
<!-- 查询订单关联查询用户,使用resultMap -->
    <select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
        SELECT
        orders.*,
        USER.username,
        USER.sex,
        USER.address
        FROM
        orders,
        USER
        WHERE orders.user_id = user.id
    </select>
  1. mapper.java
//查询订单关联查询用户信息,使用resultMap
    public List<Orders> findOrdersUserResultMap() throws Exception;
  1. 测试代码
@Test
    public void testFindOrdersUserResultMap() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        
        //调用mapper的方法
        List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();
        
        System.out.println(list);
        
        sqlSession.close();
    }

resultType和resultMap实现一对一查询小结

实现一对一查询:
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果没有查询结果的特殊要求建议使用resultType。

resultMap:需要单独定义resultMap,实现有点麻烦,如果对查询结果有特殊的要求,使用resultMap可以完成将关联查询映射pojo的属性中。

resultMap可以实现延迟加载,resultType无法实现延迟加载。

一对多查询

需求

查询订单及订单明细的信息。

sql语句

确定主查询表:订单表
确定关联查询表:订单明细表
在一对一查询基础上添加订单明细表关联即可。

SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id

分析

使用resultType将上边的 查询结果映射到pojo中,订单信息的就是重复。

要求:
对orders映射不能出现重复记录。

在orders.java类中添加List<orderDetail> orderDetails属性。
最终会将订单信息映射到orders中,订单所对应的订单明细映射到orders中的orderDetails属性中。

映射成的orders记录数为两条(orders信息不重复)
每个orders中的orderDetails属性存储了该 订单所对应的订单明细。

在orders中添加list订单明细属性

 //订单明细
    private List<Orderdetail> orderdetails;

    /**
     * @return orderdetails
     */
    public List<Orderdetail> getOrderdetails() {
        return orderdetails;
    }

    /**
     * @param orderdetails 要设置的 orderdetails
     */
    public void setOrderdetails(List<Orderdetail> orderdetails) {
        this.orderdetails = orderdetails;
    }

mapper.xml

<!-- 查询订单关联 查询用户及订单明细,使用resultMap -->
    <select id="findOrdersAndOrdersDetailResultMap" resultMap="OrdersAndOrdersDetailResultMap">
        SELECT
        orders.*,
        USER.username,
        USER.sex,
        USER.address,
        orderdetail.id orderdetail_id,
        orderdetail.items_id,
        orderdetail.items_num,
        orderdetail.orders_id
        FROM
        orders,
        USER,
        orderdetail
        WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id
    </select>

resultMap定义


    <!-- 查询订单及订单明细的resultMap
    
    使用继承,不用在此配置订单信息和用户信息的映射
        订单信息、用户信息都继承了
     -->
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrdersDetailResultMap" extends="OrdersUserResultMap">
        <!-- 订单信息 -->
        
        <!-- 用户信息 -->
        
        <!-- 订单明细信息
            一个订单关联查询出了多条明细,要使用collection进行映射
            collection:对关联查询到多条记录映射到集合中
            property:将关联查询到的多条记录映射到Orders的哪个属性
            ofType:指定映射到集合属性中pojo的类型
         -->
         <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
            <!-- id:订单明细唯一标识
            property:要将订单明细的唯一标识映射到cn.itcast.mybatis.po.Orderdetail的哪个属性
             -->
            <id column="orderdetail_id" property="id"/>
            <result column="items_id" property="itemsId"/>
            <result column="items_num" property="itemsNum"/>
            <result column="orders_id" property="ordersId"/>
            
         </collection>
    
    
    </resultMap>
    

mapper.java

//查询订单(关联用户)及订单明细
    public List<Orders> findOrdersAndOrdersDetailResultMap() throws Exception;

测试

@Test
    public void testFindOrdersAndOrdersDetailResultMap() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        
        //调用mapper的方法
        List<Orders> list = ordersMapperCustom.findOrdersUserResultMap();
        
        System.out.println(list);
        
        sqlSession.close();
    }

!](https://upload-images.jianshu.io/upload_images/17476301-eccce7a662db221a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

小结

mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。

使用resultType实现:
将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。

多对多查询

需求

查询用户及用户购买商品信息。

sql语句

查询主表是:用户表
关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:
orders、orderdetail、items

SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id,
items.name items_name,
items.detail items_detail,
items.price items_price
FROM
orders,
USER,
orderdetail,
items
WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id

映射思路

将用户信息映射到user中。
在user类中添加订单列表属性List<Orders> orderslist,将用户创建的订单映射到orderslist
在Orders中添加订单明细列表属性List<OrderDetail>orderdetials,将订单的明细映射到orderdetials
在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items

mapper.xml

<!-- 查询用户及购买的商品信息,使用resultMap -->
    <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
        SELECT
        orders.*,
        USER.username,
        USER.sex,
        USER.address,
        orderdetail.id orderdetail_id,
        orderdetail.items_id,
        orderdetail.items_num,
        orderdetail.orders_id,
        items.name items_name,
        items.detail items_detail,
        items.price items_price
        FROM
        orders,
        USER,
        orderdetail,
        items
        WHERE orders.user_id = user.id AND orderdetail.orders_id=orders.id AND orderdetail.items_id = items.id
    </select>

补充

User.java

//用户创建的订单列表
    private List<Orders> ordersList;

Orders.java

 //订单明细
    private List<Orderdetail> orderdetails;

Orderdetail.java

 //商品信息,明细对应的商品
    private Items items;

总结

将查询用户购买的商品信息明细清单,(用户名、用户地址、购买商品名称、购买商品时间、购买商品数量)

针对上边的需求就使用resultType将查询到的记录映射到一个扩展的pojo中,很简单实现明细清单的功能。

一对多是多对多的特例,如下需求:
查询用户购买的商品信息,用户和商品的关系是多对多关系。
需求1:
查询字段:用户账号、用户名称、用户性别、商品名称、商品价格(最常见)
企业开发中常见明细列表,用户购买商品明细列表,
使用resultType将上边查询列映射到pojo输出。

需求2:
查询字段:用户账号、用户名称、购买商品数量、商品明细(鼠标移上显示明细)
使用resultMap将用户购买的商品明细列表映射到user对象中。

总结:

使用resultMap是针对那些对查询结果映射有特殊要求的功能,,比如特殊要求映射成list中包括 多个list。

resultMap总结

resultType:
作用:
将查询结果按照sql列名pojo属性名一致性映射到pojo中。
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。

resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

association:
作用:
将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。

collection:
作用:
将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块下的菜单,可使用collection将模块映射到模块list中,将菜单列表映射到模块对象的菜单list属性中,这样的作的目的也是方便对查询结果集进行遍历查询。
如果使用resultType无法将查询结果映射到list集合中。

延迟加载

什么是延迟加载

resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。
需求:
如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高 数据库性能,因为查询单表要比关联查询多张表速度要快。

使用association实现延迟加载

  1. 需求
    查询订单并且关联查询用户信息

  2. mapper.xml
    需要定义两个mapper的方法对应的statement。

  • 只查询订单信息
    SELECT * FROM orders
    在查询订单的statement中使用association去延迟加载(执行)下边的satatement(关联查询用户信息)
<!-- 延迟加载的resultMap -->
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserLazyLoadingResultMap">
        <!-- 对订单信息进行映射配置 -->
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>
        
        <!-- 实现对用户信息进行延迟加载 
            select:指定延迟加载需要执行的statement的id,(是根据user_id查询用户信息的statement
                    使用userMapper.xml中的findUserById完成根据用户id(user_id)用户信息的查询,如果不在本mapper中,需要加namespace
            column:订单信息中关联用户信息查询的列,是user_id
            关联查询的sql可以理解为:SELECT orders.*,
    (SELECT username FROM USER WHERE orders.user_id = user.id)username,
    (SELECT sex FROM USER WHERE orders.user_id = user.id)sex
     FROM orders

        -->
        <association property="user" javaType="cn.itcast.mybatis.po.User" select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
            
        </association>
    
    </resultMap>
<!-- 查询订单关联查询用户,用户信息需要延迟加载 -->
    <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
        SELECT * FROM orders
    </select>
  • 关联查询用户信息
    通过上边查询到的订单信息中user_id去关联查询用户信息
    使用UserMapper.xml中的findUserById
<select id="findUserById" parameterType="int" resultType="user">
        SELECT * FROM USER WHERE id = #{id}
    </select>

上边先去执行findOrdersUserLazyLoading,当需要去查询用户的时候再去执行findUserById,通过resultMap的定义将延迟加载执行配置起来。

mapper.java

//查询订单关联查询用户,用户信息延迟加载
    public List<Orders> findOrdersUserLazyLoading() throws Exception;

测试

  • 测试思路
    1、执行上边mapper方法(findOrdersUserLazyLoading),内部去调用cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查询orders信息(单表)。
    2、在程序中去遍历上一步骤查询出的List<Orders>,当我们调用Orders中的getUser方法时,开始进行延迟加载。
    3、延迟加载,去调用UserMapper.xml中findUserbyId这个方法获取用户信息。

  • 延迟加载配置

mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。

在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading

SqlMapConfig.xml

<!-- 需要再用 全局配置参数 -->
    <settings>
        <!-- 打开延迟加载的开关 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 将积极加载改为校级加载,即按需加载 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
  • 测试代码
//查询订单关联查询用户,用户信息使用延迟加载
    @Test
    public void testFindOrdersUserLazyLoading() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //创建代理对象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        
        //调用mapper的方法
        List<Orders> list = ordersMapperCustom.findOrdersUserLazyLoading();
        
        //遍历上面的订单列表
        for(Orders orders:list) {
            //执行getUser()去查询用户信息,这里实现按需加载
            User user = orders.getUser();
            System.out.println(user);
            
        }
        
        sqlSession.close();
    }

id一样走了一级缓存

  1. 思考

不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载??

实现方法如下:
定义两个mapper方法:
1、查询订单列表
2、根据用户id查询用户信息
实现思路:
先去查询第一个mapper方法,获取订单信息列表
在程序中(service),按需去调用第二个mapper方法去查询用户信息。

总之:
使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容