(九)mybatis之延迟加载

一、为什么要使用延迟加载?

  • 使用延迟加载的意义

    在进行数据查询时,为了提高数据库查询性能,尽量使用单表查询,因为单表查询比多表关联查询速度快。

    如果查询单表就可以满足需求,一开始先查询单表,当需要关联信息时,再关联查询。当需要关联信息时才进行查询就叫做延迟加载。mybatis中resultMap提供延迟加载功能,通过resultMap配置延迟加载。

在mybatis-config.xml中配置全局参数

<!-- 全局配置参数 -->  
    <settings>  
       <!-- 延迟加载总开关 -->  
       <setting name="lazyLoadingEnabled" value="true"/>  
       <!-- 设置按需加载 -->  
       <setting name="aggressiveLazyLoading" value="false"/>  
    </settings>  

 

 

二、案例

  • 需求:查询订单并且关联查询消费者信息,要求只有使用到消费者信息的时候才发送查询用户信息的sql语句。

 

2.1   创建数据库表和实体对象

 

 Customer.java

package com.shyroke.entity;

public class Customer {
    private int user_id;
    private String user_name;
    private String user_sex;
    private String user_birthday;
//隐藏get和set方法

 Order.java

package com.shyroke.entity;

public class Orders {
    private int order_id;
    private String order_number;
    private String order_createTime;
    private String order_note;
    private String user_id;
//消费者信息,为了保存查询得到的关联的User表的信息(一对一)
    private Customer customer;
//隐藏get和set方法

 

2.2 创建OrderMapper.java接口和   OrderMapper.xml配置文件

    OrderMapper.java

package com.shyroke.mapper;


import java.util.List;

import com.shyroke.entity.Orders;

public interface OrderMapper {
        public List<Orders> selectOrderByLazyLoading();
}

    OrderMapper.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.shyroke.mapper.OrderMapper">
    
    <resultMap type="com.shyroke.entity.Customer" id="customerMap">
        <id column="user_id" property="user_id"/>
        <result column="user_name" property="user_name"/>
        <result column="user_sex" property="user_sex"/>
        <result column="user_birthday" property="user_birthday"/>
    </resultMap>
    
    <resultMap type="com.shyroke.entity.Orders" id="orderByLazyLoading">
        <id column="order_id" property="order_id"/>
        <result column="order_number" property="order_number"/>
        <result column="order_createTime" property="order_createTime"/>
        <result column="order_note" property="order_note"/>
        <result column="user_id" property="user_id"/>
        
        <association property="customer" select="findCustomerById" column="user_id"></association>
    </resultMap>
    
    
    <select id="findCustomerById" parameterType="int" resultMap="customerMap">
        SELECT * FROM CUSTOMER WHERE user_id=#{value}
    </select>
    
    <select id="selectOrderByLazyLoading" resultMap="orderByLazyLoading">
        SELECT * FROM orders
    </select>
</mapper>
  • association标签中的select属性:延迟加载执行的sql所在的statement的id,如果不在同一个namespace需要加namespace  。

        sql:根据用户id查询消费者信息 column:关联查询的列   

        property:将关联查询的用户信息设置到Orders的哪个属性

  • 整个流程大概为:当需要用到消费者信息时才会发送association标签中select="findCustomerById"对应的select标签中id=“findCustomerById”的sql语句。

2.3 在总配置文件中打开延迟加载的开启

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <!-- 配置数据库连接信息 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;useJDBCCompliantTimezoneShift=true&amp;useLegacyDatetimeCode=false&amp;serverTimezone=UTC" /> <property name="username" value="root" /> <property name="password" value="" /> </dataSource> </environment> </environments> <mappers> <package name="com.shyroke.mapper"/> </mappers> </configuration>

 

 2.4   测试

 

package com.shyrolk.firstMybatis;

import java.io.IOException;
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 com.shyroke.entity.Orders;
import com.shyroke.mapper.OrderMapper;

/**
 * Hello world!
 *
 */
public class App {
    public static void main(String[] args) throws IOException {
        String resource = "resource/mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        SqlSession session = sessionFactory.openSession();

        OrderMapper orderMapper = session.getMapper(OrderMapper.class);
        List<Orders> orderList = orderMapper.selectOrderByLazyLoading();

        System.out.println(orderList.get(0).getOrder_id());
    
    }
}

结果:

  • 一对多查询延迟加载

    一对多延迟加载的方法同一对一延迟加载,在collection标签中配置select内容。
posted @ 2017-09-28 16:52  shyroke、  阅读(289)  评论(0编辑  收藏  举报
作者:shyroke 博客地址:http://www.cnblogs.com/shyroke/ 转载注明来源~