MyBatis声明式延迟加载

1. 延迟加载

描述:延迟加载又名懒加载、按需加载,即我们需要这个数据的时候才去加载这个数据。在MyBatis框架中通过设置或标签的fetchType属性值为lazy来指按需加载。

需求:在用户与账户一对一关联查询的基础上,查询指定用户信息及其账户信息,对账户信息的查询实现延迟加载。

2. 数据库环境

2.1 表的创建

# 创建用户表
CREATE TABLE IF NOT EXISTS `user`(
  `id` INT AUTO_INCREMENT,
  `username` VARCHAR(32) NOT NULL,
  `birthday` DATETIME NOT NULL,
  `sex` CHAR(1) NOT NULL,
  `address` VARCHAR(256),
  CONSTRAINT pk_user PRIMARY KEY(`id`)
);

# 添加用户数据
INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES 
(NULL,'周瑜','2020-02-27 17:47:08','男','吴国'),
(NULL,'大乔','2020-02-27 15:09:37','女','吴国'),
(NULL,'小乔','2020-02-27 11:34:34','女','吴国'),
(NULL,'陆逊','2020-02-27 12:04:06','男','吴国'),
(NULL,'孙策','2020-02-27 17:37:26','男','东吴'),
(NULL,'孙尚香','2020-02-27 11:44:00','女','吴国'),
(NULL,'曹操','2020-07-29 16:36:26','男','魏国');

# 创建账户表
CREATE TABLE IF NOT EXISTS `account`(
  `id` INT AUTO_INCREMENT,
  `user_id` INT NOT NULL,
  `money` DOUBLE NOT NULL,
  CONSTRAINT pk_account PRIMARY KEY(`id`),
  CONSTRAINT fk_account_user FOREIGN KEY(`user_id`) REFERENCES `user`(`id`)
);

# 添加账户数据
INSERT  INTO `account`(`id`,`user_id`,`money`) VALUES 
(1,6,1000),
(2,3,1000),
(3,1,2000);

2.2 表与表的关系

在这里插入图片描述

3. 用户实体类

package zw.mybatis.bean.domain;

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

/**
 * @className UserDO
 * @description 用户实体类
 * @author 周威
 * @date 2020-07-31 14:14
 **/
public class UserDO implements Serializable
{
    /* 用户编号 */
    private Integer id;
    /* 用户姓名 */
    private String userName;
    /* 用户生日 */
    private Date birthday;
    /* 用户性别 */
    private String sex;
    /* 用户地址 */
    private String address;

    /* Getter和Setter方法 */
    public Integer getId()
    {
        return id;
    }

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

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public Date getBirthday()
    {
        return birthday;
    }

    public void setBirthday(Date birthday)
    {
        this.birthday = birthday;
    }

    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;
    }

    /* toString()方法 */
    @Override
    public String toString()
    {
        return "UserDO{" + "id=" + id + ", userName='" + userName + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}';
    }
}

4. 账户实体类

package zw.mybatis.bean.domain;

import java.io.Serializable;

/**
 * @className AccountDO
 * @description 账户实体类
 * @author 周威
 * @date 2020-08-07 14:03
 **/
public class AccountDO implements Serializable
{
    /* 账户编号 */
    private Integer id;
    /* 用户编号 */
    private Integer userId;
    /* 账户金额 */
    private Double money;

    /* Getter和Setter方法 */
    public Integer getId()
    {
        return id;
    }

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

    public Integer getUserId()
    {
        return userId;
    }

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

    public Double getMoney()
    {
        return money;
    }

    public void setMoney(Double money)
    {
        this.money = money;
    }

    /* toString()方法 */
    @Override
    public String toString()
    {
        return "AccountDO{" + "id=" + id + ", userId=" + userId + ", money=" + money + '}';
    }
}

5. 用户展示实体类

package zw.mybatis.bean.vo;

import zw.mybatis.bean.domain.AccountDO;
import zw.mybatis.bean.domain.UserDO;
import java.io.Serializable;

/**
 * @className UserVO
 * @description 用户展示实体类
 * @author 周威
 * @date 2020-08-03 18:31
 **/
public class UserVO extends UserDO implements Serializable
{
    /* 账户信息 */
    private AccountDO accountDO;

    /* Getter和Setter方法 */
    public AccountDO getAccountDO()
    {
        return accountDO;
    }

    public void setAccountDO(AccountDO accountDO)
    {
        this.accountDO = accountDO;
    }

    /* toString()方法 */
    @Override
    public String toString()
    {
        return "UserVO{userDO="+ super.toString() + "accountDO=" + accountDO + '}';
    }
}

6. 账户持久层接口

package zw.mybatis.mapper;

import zw.mybatis.bean.domain.AccountDO;

/**
 * @className AccountMapper
 * @description 账户持久层接口
 * @author 周威
 * @date 2020-08-07 14:06
 **/
public interface AccountMapper
{
    /**
     * 查询账户信息,根据用户编查询指定账户信息
     * @param userId
     * @return 账户信息
     */
    AccountDO findAccountInformationByUserId(Integer userId);
}

7. 账户映射文件

<?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="zw.mybatis.mapper.AccountMapper">
    <!-- 输出映射 -->
    <resultMap id="accountDOResultMap" type="zw.mybatis.bean.domain.AccountDO">
        <id column="id" property="id" javaType="java.lang.Integer"/>
        <result column="userId" property="userId" javaType="java.lang.Integer"/>
        <result column="money" property="money" javaType="java.lang.Double"/>
    </resultMap>

    <!-- 查询账户信息,根据用户编查询指定账户信息 -->
    <select id="findAccountInformationByUserId" parameterType="java.lang.Integer" resultMap="accountDOResultMap">
        select
         id id,
         user_id userId,
         money money
        from
         account
        where
         user_id = #{userId}
    </select>
</mapper>

8. 用户持久层接口

package zw.mybatis.mapper;

import zw.mybatis.bean.vo.UserVO;

/**
 * @className UserMapper
 * @description 用户持久层接口
 * @author 周威
 * @date 2020-07-31 14:18
 **/
public interface UserMapper
{
    /**
     * 查询用户信息,根据用户编号查询用户信息及其账户信息,实现账户信息查询的延迟加载
     * @param userId
     * @return 用户信息
     */
    UserVO findUserInformationAndAccountByUserId(Integer userId);
}

9. 用户映射文件

<?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="zw.mybatis.mapper.UserMapper">
    <!-- 输出映射 -->
    <resultMap id="userVOResultMap" type="zw.mybatis.bean.vo.UserVO">
        <!-- 用户信息映射 -->
        <id column="id" property="id" javaType="java.lang.Integer"/>
        <result column="userName" property="userName" javaType="java.lang.String"/>
        <result column="birthday" property="birthday" javaType="java.util.Date"/>
        <result column="sex" property="sex" javaType="java.lang.String"/>
        <result column="address" property="address" javaType="java.lang.String"/>
        <!-- 用户与账户一对一映射 -->
        <association column="id" property="accountDO" javaType="zw.mybatis.bean.domain.AccountDO" fetchType="lazy" select="zw.mybatis.mapper.AccountMapper.findAccountInformationByUserId"></association>
    </resultMap>
    <!-- 查询用户信息,根据用户编号查询用户信息及其账户信息,实现账户信息查询的延迟加载 -->
    <select id="findUserInformationAndAccountByUserId" parameterType="java.lang.Integer" resultMap="userVOResultMap">
        select
         id id,
         username userName,
         birthday birthday,
         sex sex,
         address address
        from
         user
        where id = #{userId}
    </select>
</mapper>

10. 用户持久层测试类

package zw.mybatis.mapper;

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.Test;
import zw.mybatis.bean.vo.UserVO;
import java.io.IOException;
import java.io.InputStream;

/**
 * @className UserMapperTest
 * @description 用户持久层测试类
 * @author 周威
 * @date 2020-07-31 14:27
 **/
public class UserMapperTest
{
    @Test
    public void findUserInformationAndRoleByUserIdTest()
    {
        InputStream is = null;
        SqlSession sqlSession = null;
        try
        {
            // 读取配置文件
            is = Resources.getResourceAsStream("mybatis/mybatis.xml");
            // 创建SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            // 获取SqlSessionFactory对象
            SqlSessionFactory factory = builder.build(is);
            // 获取SqlSession对象
            sqlSession = factory.openSession();
            // 获取代理对象
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            // 查询数据记录
            UserVO userVO = userMapper.findUserInformationAndAccountByUserId(1);

            // 打印用户信息
            System.out.println("---------------用户信息---------------");
            System.out.println("用户编号:" + userVO.getId());
            System.out.println("用户姓名:" + userVO.getUserName());
            System.out.println("用户生日:" + userVO.getBirthday());
            System.out.println("用户性别:" + userVO.getSex());
            System.out.println("用户住址:" + userVO.getAddress());

            // 打印账户信息
            System.out.println("---------------角色信息---------------");
            System.out.println("账户编号:" + userVO.getAccountDO().getId());
            System.out.println("用户编号:" + userVO.getAccountDO().getUserId());
            System.out.println("账户金额:" + userVO.getAccountDO().getMoney());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                // 关闭资源
                if(sqlSession != null)
                    sqlSession.close();
                if(is != null)
                    is.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

11. 运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值