Mybatis 延迟加载

什么是延迟加载?

讲延迟加载也叫懒加载。延迟加载就是在关联查询时,利用延迟加载,先加载主信息,使用关联信息时再去加载关联信息。

 resultMap中的association和collection标签具有延迟加载的功能。

配置延迟加载

在SqlMapConfig.xml文件,<settings>标签中设置下延迟加载。

<settings>
	<!--开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
	<!--关闭积极加载 -->
	<setting name="aggressiveLazyLoading" value="false" />
</settings>

实现延迟加载示例

现在有三张表,文章表:article;用户表:user;文章标签表:tag。

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '文章id',
  `title` varchar(100) NOT NULL COMMENT '标题',
  `userId` int(11) NOT NULL COMMENT '用户id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='文章表';

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(10) NOT NULL COMMENT '姓名',
  `gender` char(1) DEFAULT NULL COMMENT '性别,M-男,F-女',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

CREATE TABLE `tag` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(20) NOT NULL COMMENT '标签名称',
  `articleId` int(11) NOT NULL COMMENT '文章id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章标签表';

article表中一条记录对应user中一条记录,对应tag表中多条记录,现在查询article表信息时也要查询article对应的user和tag。

(1)编写三张表对应的实体类

Article实体类中包含user和tags,如下:

package com.lzgsea.entity;

import java.util.List;

public class Article {
	private Integer id;
	private String title;
	private Integer userId;
	private User user;
	private List<Tag> tags;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public List<Tag> getTags() {
		return tags;
	}

	public void setTags(List<Tag> tags) {
		this.tags = tags;
	}

	@Override
	public String toString() {
		return "Article [id=" + id + ", title=" + title + ", userId=" + userId + ", user=" + user + ", tags=" + tags
				+ "]";
	}

}

(2)编写sql语句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.lzgsea.mapper.ArticleMapper">

	<resultMap id="BaseResultMap" type="com.lzgsea.entity.Article">
        <id column="id" property="id" />
        <result column="title" property="title" />
        <result column="userId" property="userId" />
        <association property="user" column="userId" select="getUser"></association>
        <collection property="tags" column="userId" select="getTags"></collection>
    </resultMap>
    
    <select id="getList" resultMap="BaseResultMap">
    	select *  from article
    </select>
    
    <select id="getUser" resultType="com.lzgsea.entity.User">
    	select * from user
    </select>
    
    <select id="getTags" resultType="com.lzgsea.entity.Tag">
    	select * from tag
    </select>

</mapper>

注意:由于是懒加载是分开查询,所以我们的每个select 映射也需要分开写。 association查询是一对一关系,collection查询是一对多关系。

association 和 collection 标签中的 column 和select属性:

select: 需要调用的 select 映射的 id ;

column : 传递给 select 映射的 参数。

(3)测试

package com.lzgsea.test;

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.lzgsea.entity.Article;
import com.lzgsea.mapper.ArticleMapper;

public class MyTest {
	
	private static SqlSessionFactory sqlSessionFactory;

	public static SqlSession getSqlSession() {
		if (sqlSessionFactory == null) {
			String resource = "SqlMapConfig.xml";
			InputStream inputStream = null;
			try {
				inputStream = Resources.getResourceAsStream(resource);
			} catch (IOException e) {
				e.printStackTrace();
			}
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		}
		return sqlSessionFactory.openSession();
	}

	public static void main(String[] args) {
		SqlSession sqlSession = getSqlSession();
		try {
			ArticleMapper articleMapper = sqlSession.getMapper(ArticleMapper.class);
			List<Article> list = articleMapper.getList();
			for (Article a : list) {
				System.out.println(a.getTitle());
				System.out.println(a.getTags());
				System.out.println(a.getUser());
			}
		} finally {
			sqlSession.close();
		}
	}

}

user和tags只有在我们使用时才会从数据库中查询,不使用时不会查询。上面代码中我们调用getUser()时,mybatis才会查询查询user表,调用getTags()时才会查询tag表。

如果我们想在查询article表时就直接查询user表和tag表,只要将aggressiveLazyLoading设为true就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值