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