延時加載和立即加載
- 延遲加載:在真正使用數據時才發起查詢,不用的時候不查詢。按需加載(懶加載)
- 立即加載:不管是否使用數據,只要一調用方法,馬上發起查詢。
Mybatis中選擇延時、立即加載
- 一對多,多對多:通常情況下采用延遲加載。
- 多對一,一對一:通常情況下采用立即加載。
一對一實現延時加載
需求:查詢一個賬戶時,同時查詢出該賬戶的所屬用戶信息,使用延時加載
*從表實體應該包含一個主表實體的對象引用
IAccountDao中的方法:
/**
* 查詢所有賬戶,同時還要獲取到當前賬戶的所屬用戶信息
* @return
*/
List<Account> findAll();
IAccountDao.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.sx.dao.IAccountDao">
<!-- 定義封裝account和user的resultMap -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一對一的關係映射:配置封裝user的內容-->
<!--
select屬性制定的內容:查詢用戶的唯一標識
column屬性指定內容:根據用戶id查詢時,所需要的參數的值
-->
<association property="user" column="uid" javaType="user" select="com.sx.dao.IUserDao.findById">
<!-- 對應的IUserDao.xml中的findById方法:根據id查詢用戶 -->
<!-- <select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>-->
</association>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
</mapper>
要想使用延時加載,主配置文件中需要的配置
<!--配置參數-->
<settings>
<!--全局延時加載-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
測試類代碼以及測試結果
public class AccountTest {
private InputStream in;
private SqlSession sqlSession;
private IAccountDao accountDao;
@Before//用於在測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成字節輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取SqlSession對象
sqlSession = factory.openSession(true);
//4.獲取dao的代理對象
accountDao = sqlSession.getMapper(IAccountDao.class);
}
@After//用於在測試方法執行之後執行
public void destroy()throws Exception{
//提交事務
// sqlSession.commit();
//6.釋放資源
sqlSession.close();
in.close();
}
/**
* 測試查詢所有
*/
@Test
public void testFindAll(){
List<Account> accounts = accountDao.findAll();
for(Account account : accounts){
System.out.println("--------每個account的信息------------");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
延時加載
立即加載
一對多實現延時加載
需求:查詢一個用戶時,同時查詢該用戶所有的賬戶信息,使用延時加載
*主表實體應該包含從表實體的集合引用
IUserDao中的方法:
/**
* 查詢所有用戶,同時獲取到用戶下所有賬戶的信息
* @return
*/
List<User> findAll();
IUserDao.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.sx.dao.IUserDao">
<!-- 定義User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置user對象中accounts集合的映射 -->
<collection property="accounts" ofType="account" column="id" select="com.sx.dao.IAccountDao.findAccountByUid">
<!-- 對應的IAccountDao.xml中的方法:根據用戶id查詢賬戶列表 -->
<!--<select id="findAccountByUid" resultType="account">
select * from account where uid = #{uid}
</select>-->
</collection>
</resultMap>
<!-- 查詢所有 -->
<select id="findAll" resultMap="userAccountMap">
select * from user
</select>
<!-- 根據id查詢用戶 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
</mapper>
測試類代碼以及測試結果
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用於在測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成字節輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取SqlSession對象
sqlSession = factory.openSession(true);
//4.獲取dao的代理對象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//用於在測試方法執行之後執行
public void destroy()throws Exception{
//提交事務
// sqlSession.commit();
//6.釋放資源
sqlSession.close();
in.close();
}
/**
* 測試查詢所有
*/
@Test
public void testFindAll(){
List<User> users = userDao.findAll();
for(User user : users){
System.out.println("-----每個用戶的信息------");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
}