Mybatis框架|延迟加载


一、延迟加载介绍

在操作数据库时,尽量查询单表,因为查询单表的效率最高。但很多时候难免要进行多表查询,这时使用延迟加载,就可以提高关联查询的效率。并且延迟加载只能使用resultMap。

二、测试延迟加载

  • 下面setting标签中的配置是设置懒加载的两行代码,使用时将其放在全局配置文件中。另外,在dao配置文件中的sql语句也进行了拆分。
  • 这里有一个小技巧:如果要在一个xml文件中引用另外一个xml文件中的sql语句,就需要使用另一个xml文件的命名空间.id号。
	<settings>
		<setting name="lazyLoadingEnabled" value="true"/>
 		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

1.创建两张数据库表

创建user表和orders表进行测试,手动添加记录如下:

User表

CREATE TABLE `user` (
	`id` INT(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
	`username` VARCHAR(50) NULL DEFAULT NULL COMMENT '姓名',
	`sex` VARCHAR(1) NULL DEFAULT NULL COMMENT '性别',
	`address` VARCHAR(200) NULL DEFAULT NULL COMMENT '住址',
	`birthday` DATE NULL DEFAULT NULL COMMENT '生日',
	PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1
;

在这里插入图片描述
orders订单表

CREATE TABLE `orders` (
	`id` INT(10) NOT NULL AUTO_INCREMENT,
	`creattime` DATETIME NULL DEFAULT NULL,
	`number` VARCHAR(50) NULL DEFAULT NULL,
	`user_id` INT(10) NULL DEFAULT NULL,
	`count` INT(10) NULL DEFAULT NULL,
	PRIMARY KEY (`id`),
	INDEX `FK_user_id` (`user_id`),
	CONSTRAINT `FK_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=4
;

在这里插入图片描述

2.两张表的pojo以及扩展pojo

(1)Orders的pojo

package com.gql.pojo;

import java.io.Serializable;
import java.util.Date;

/**
 * 类说明:
 *		Orders_JavaBean
 * @guoqianliang1998.
 */
public class Orders implements Serializable{

	private static final long serialVersionUID = 1L;
	private int id;
	private Date creattime;
	private String number;
	private int user_id;
	private int count;
	private User user;
	
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Date getCreattime() {
		return creattime;
	}
	public void setCreattime(Date creattime) {
		this.creattime = creattime;
	}
	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
	public int getUser_id() {
		return user_id;
	}
	public void setUser_id(int user_id) {
		this.user_id = user_id;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
}

(2)User的pojo

package com.gql.pojo;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
 * 类说明:
 *		User_JavaBean
 * @guoqianliang1998.
 */
public class User implements Serializable{

	private static final long serialVersionUID = 1L;
	private int id;
	private String username;
	private String sex;
	private String address;
	private Date birthday;
	//用户关联多个订单对象
	private List<Orders> orderList;
	
	public List<Orders> getOrderList() {
		return orderList;
	}
	public void setOrderList(List<Orders> orderList) {
		this.orderList = orderList;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}

(3)扩展类的pojo

package com.gql.pojo.custom;

import com.gql.pojo.Orders;
/**
 * 类说明:
 *		Orders_pojo扩展类
 * @guoqianliang1998.
 */
public class OrdersCustom extends Orders {
	private String username;
	private String sex;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
}

3.dao接口

package com.gql.mapper.custom;

import java.util.List;

import com.gql.pojo.custom.OrdersCustom;

/**
 * 类说明:
 *		dao层接口
 * @guoqianliang1998.
 */
public interface OrdersMapperCustom {
	

	List<OrdersCustom> getOrdersLazyLoading();
}

4.dao配置文件

<?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.gql.mapper.custom.OrdersMapperCustom">
	<select id="getOrders" resultType="com.gql.pojo.custom.OrdersCustom">
		SELECT 
		o.id,
		o.creattime,
		o.number,
		o.user_id,
		o.count,
		u.username,
		u.sex
		FROM orders o, USER u
		WHERE u.id=o.user_id;
	</select>
	
	<select id="getOrdersLazyLoading" resultMap="getOrdersLazyLoadingMap">
			SELECT 
			o.id,
			o.creattime,
			o.number,
			o.user_id,
			o.count
			FROM orders o;
	</select>
	
	<resultMap type="com.gql.pojo.custom.OrdersCustom" id="getOrdersLazyLoadingMap">
		<id column="id" property="id"/>
		<result column="creattime" property="creattime"/>
		<result column="number" property="number"/>
		<result column="user_id" property="user_id"/>
		<result column="count" property="count"/>
		<association property="user" column="user_id" select="getOrdersLazySelect"></association>
	</resultMap>
	 
	<select id="getOrdersLazySelect" parameterType="int" resultType="com.gql.pojo.User">
		select * from user where id=#{id}
	</select>
</mapper>

5.全局mybatis-config.xml配置文件

<?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>
	<properties resource="db.properties"></properties>
	<!-- 设置懒加载 -->
	
	<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="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- 使用接口的全限定名,接口名必须和sql配置文件同名且同级目录 -->
		
		<package name="com.gql.mapper"/>
	</mappers>
</configuration>

6.测试延迟加载

package com.gql.mapper.custom;

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 org.junit.Before;
import org.junit.Test;

import com.gql.pojo.custom.OrdersCustom;
/**
 * 类说明:
 *		使用扩展pojo测试dao层
 * @guoqianliang1998.
 */
public class OrdersMapperCustomTest {
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void init() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);		
	}

	@Test
	public void testgetOrdersLazyLoading(){
		SqlSession session = sqlSessionFactory.openSession();
		OrdersMapperCustom mapper = session.getMapper(OrdersMapperCustom.class);
		List<OrdersCustom> list = mapper.getOrdersLazyLoading();
		System.out.println(list.get(0).getUser().getUsername());
	}
}

在debug模式下运行测试代码,可以看到当还没有访问扩展类对象OrdersCustom中的User对象的username属性时,此时只执行了一条sql语句。
在这里插入图片描述
当按下F6下一步,此时运行了打印语句,第二条sql语句才执行。
在这里插入图片描述

延迟加载测试成功。

发布了412 篇原创文章 · 获赞 1080 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/104301144
今日推荐