从来就没有救世主  也不靠神仙皇帝  要创造人类的幸福  全靠我们自己  

mybatis--

  延迟加载与按需加载

 

  例:一张订单表,表里面有用户id字段,当执行查询订单时,可能需要根据用户id查询用户信息,也可能不需要。因此可对查询用户信息实行延迟加载。当没有获取用户信息的操作出现时,即不执行用户信息查询。

    这里即将两个sql语句分开执行

 

1. 设置

  默认设置:

<settings>
    <setting name="lazyLoadingEnabled" value="false"/>
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>

 

  lazyLoadingEnable:是否启用延迟加载

  aggressiveLazyLoading:是否按需加载属性。为true时,当启用延迟加载时,只要加载对象,就加载对象的所有属性

    真正需要的是按需加载:延迟加载开启(lazyLoadingEnabled为true),且按需加载开启(aggressiveLazyLoading为false)

               若延迟加载关闭,则按需加载无论开启还是关闭,一开始所有sql都会执行

 

2. 测试

  2.1 准备两张表

//测试mybatis延迟加载
create table orders(id int primary key,
                    user_id int,
                    createtime timestamp default current_timestamp,
                    note varchar(20)
                    );

create table users(id int primary key auto_increment,
                   name varchar(20),
                   age int,
                   sex varchar(10),
                   money double
                   );
                  

  表orders有 user_id 字段,通过此字段可以去查询uses表获取user信息

 

  2.2 实体类

  Order.java(表orders有4个字段,但实体类有第五个属性,这第五个属性即是展现延迟加载的地方)

public class Order {
    private int id;
    private int userId;
    private Date createTime;
    private String note;
    private User userInfo;
    
    getter、setter
    toString()
}

 

  User.java

public class User {
    private int id;
    private String name;
    private int age;
    private String sex;
    Double money;
    
    getter、setter
}

 

  延迟加载说明:当我们查询orders里面的信息,映射到Order实体类上时,如果不需要根据Order的 userInfo 字段去获取User信息,则不执行查询User的操作;当需要时才去执行

 

  2.3 OrderDao、UserDao以及他们的映射文件

  OrderDao.java

public interface OrderDao {
    /*查询订单信息*/
    List<Order> findAllOrders();
}

  OrderDao.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.xt.dao.OrderDao">
    <!--配置查询所有-->
    <select id="findAllOrders" resultMap="orderInfoResMap">
        select * from orders
    </select>

    <resultMap type="com.xt.domain.Order" id="orderInfoResMap">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="createtime" property="createTime"/>
        <result column="note" property="note"/>
        <association property="userInfo" select="com.xt.dao.UserDao.findUserById" column="user_id"></association>  <!--按需加载的地方-->
    </resultMap>

</mapper>

 

  UserDao.java

public interface UserDao {
    /*根据订单id查询*/
    User findUserById(int id);
}

  UserDao.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.xt.dao.UserDao">
    <select id="findUserById" parameterType="int" resultType="com.xt.domain.User">
        select * from users where id = #{id}
    </select>
</mapper>

 

  2.4 测试

(1)开启延迟加载,开启按需加载

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

  

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
OrderDao orderDao = session.getMapper(OrderDao.class);
//通过代理对象调用方法
List<Order> allOrders = orderDao.findAllOrders();
Order order = allOrders.get(0);
String note = order.getNote();

//String name = order.getUserInfo().getName();

session.close();
is.close();

  测试结果:因为没有调用 getUserInfo(),则就不需要根据order里面的user_id 去查询用户信息了,mybatis日志输出发现只执行了查询orders表的sql

       如果执行 getUserInfo,则会执行根据 user_id 查询 users 表的sql

 

(2)开启延迟加载,关闭按需加载

  关闭了按需加载,则只要去获取Order的某个属性,所有的属性都会加载(包括本来要延迟加载的 userInfo 字段信息)

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>

  测试代码同上,但当执行到 getNote() 时,第二个sql(根据 user_id 去查第二张表)也会执行

 

  

 

  

 

posted @ 2020-06-22 22:34  T,X  阅读(120)  评论(0编辑  收藏  举报