MyBatis注解式延迟加载

1. 延迟加载

描述:延迟加载又名懒加载、按需加载,即我们需要这个数据的时候才去加载这个数据。在注解开发中可以通过设置@One或@Many的fetchType = 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 lombok.Data;
import java.io.Serializable;
import java.util.Date;

/**
 * @ClassName UserDO
 * @Description 用户实体类
 * @Author 周威
 * @Date 2020-08-15 - 15:15
 */
@Data
public class UserDO implements Serializable
{
    /* 用户编号 */
    private Integer id;
    /* 用户姓名 */
    private String userName;
    /* 用户生日 */
    private Date birthday;
    /* 用户性别 */
    private String sex;
    /* 用户住址 */
    private String address;
}

4. 账户实体类

package zw.mybatis.bean.domain;

import lombok.Data;
import java.io.Serializable;

/**
 * @ClassName AccountDO
 * @Description 账户实体类
 * @Author 周威
 * @Date 2020-08-15 - 15:18
 */
@Data
public class AccountDO implements Serializable
{
    /* 账户编号 */
    private Integer id;
    /* 用户编号 */
    private Integer userId;
    /* 账户金额 */
    private Double money;
}

5. 用户展示实体类

package zw.mybatis.bean.domain.vo;

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

/**
 * @ClassName UserVO
 * @Description 用户展示实体类
 * @Author 周威
 * @Date 2020-08-15 - 15:20
 */
@Data
public class UserVO extends UserDO implements Serializable
{
    /* 账户信息 */
    private AccountDO accountDO;
}

6. 账户持久层接口

package zw.mybatis.mapper;

import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import zw.mybatis.bean.domain.AccountDO;

/**
 * @ClassName AccountMapper
 * @Description 账户持久层接口
 * @Author 周威
 * @Date 2020-08-15 - 15:21
 */
public interface AccountMapper
{
    /**
     * 查询账户信息,根据用户编号查询指定账户信息
     * @param userId
     * @return 账户信息
     */
    @Results({
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "user_id", property = "userId"),
            @Result(column = "money", property = "money")
    })
    @Select("select * from account where user_id = #{userId}")
    AccountDO findAccountInformationByUserId(Integer userId);
}

7. 用户持久层接口

package zw.mybatis.mapper;

import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import zw.mybatis.bean.domain.vo.UserVO;

/**
 * @ClassName UserMapper
 * @Description 用户持久层接口
 * @Author 周威
 * @Date 2020-08-15 - 15:24
 */
public interface UserMapper
{
    /**
     * 查询用户信息,根据用户编号查询指定用户信息及其账户信息,实现账户信息的延迟加载
     * @param userId
     * @return 用户信息
     */
    @Results({
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "userName"),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "sex", property = "sex"),
            @Result(column = "address", property = "address"),
            @Result(column = "id", property = "accountDO", one = @One(fetchType = FetchType.LAZY, select = "zw.mybatis.mapper.AccountMapper.findAccountInformationByUserId"))
    })
    @Select("select * from user where id = #{userId}")
    UserVO findUserInformationAndAccountByUserId(Integer userId);
}

8. 用户持久层测试类

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.domain.vo.UserVO;
import java.io.IOException;
import java.io.InputStream;

/**
 * @ClassName UserMapperTest
 * @Description 用户持久层测试类
 * @Author 周威
 * @Date 2020-08-15 - 15:30
 */
public class UserMapperTest
{
    @Test
    public void findUserInformationAndAccountByUserIdTest()
    {
        InputStream is = null;
        SqlSession sqlSession = null;
        try
        {
            // 读取mybatis配置文件
            is = Resources.getResourceAsStream("mybatis/mybatis.xml");
            // 创建SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            // 获取SqlSessionFactory对象
            SqlSessionFactory factory = builder.build(is);
            // 获取SqlSession对象
            sqlSession = factory.openSession();
            // 获取UserMapper代理对象
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            // 查询数据记录
            UserVO userVO = userMapper.findUserInformationAndAccountByUserId(1);
            // 打印用户信息
            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("账户编号:" + 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();
            }
        }
    }
}

9. 运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值