什么是延迟加载
- 需要数据时才加载,不需要不加载。
- 好处:先从单表查询,需要时再从关联表去关联查询,提高数据库性能。
- 坏处:大批量查询数据时,耗时较长。
实现需求
需求: 查询Account信息并且关联查询User信息。如果先查询Account即可满足要求,当需要查询User时再查询User信息。
实现方法: 通过association、collection实现一对一、一对多映射,具备延迟加载功能
使用assocation实现延迟加载
编写Account的持久层DAO接口
public interface IAccountDao {
/**
* 查询所有账户,同时获取账户的所属用户名称以及它的地址信息 * @return */
List<Account> findAll(); }
账户的持久层映射文件
<mapper namespace="com.itheima.dao.IAccountDao">
<!-- 建立对应关系 -->
<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- 它是用于指定从表方的引用实体属性的 -->
<association property="user" javaType="user" select="com.itheima.dao.IUserDao.findById" column="uid">
</association>
</resultMap>
<select id="findAll" resultMap="accountMap">
select * from account
</select>
</mapper>
select: 填写要调用的select映射的id
column: 填写要传递给select映射的参数
User的持久层接口和映射文件
public interface IUserDao { /**
* 根据 id 查询 * @param userId * @return */
User findById(Integer userId); }
<mapper namespace="com.itheima.dao.IUserDao">
<!-- 根据 id 查询 -->
<select id="findById" resultType="user" parameterType="int" >
select * from user where id = #{uid}
</select>
</mapper>
开启延迟加载
再配置文件SqlMapConfig.xml文件中添加延迟加载的配置
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
编写测试类只查账户信息不差用户信息
public class AccountTest {
private InputStream in ;
private SqlSessionFactory factory;
private SqlSession session;
private IAccountDao accountDao;
@Test public void testFindAll() {
//6.执行操作
List<Account> accounts = accountDao.findAll();
}
@Before
//在测试方法执行之前执行
public void init()throws Exception {
//1.读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建 SqlSession 工厂对象
factory = builder.build(in);
//4.创建 SqlSession 对象
session = factory.openSession();
//5.创建 Dao 的代理对象
accountDao = session.getMapper(IAccountDao.class); }
@After
//在测试方法执行完成之后执行
public void destroy() throws Exception{
//7.释放资源
session.close();
in.close();
}
}
使用Collection实现延迟加载
需求:完成加载用户对象是,查询该用户所拥有的账户信息
在User实体类中加入List
private List accounts;
public List getAccounts() {
return accounts;
}
public void setAccounts(List accounts) {
this.accounts = accounts;
}
编写User和Account DAO 层接口的方法
List<User> findAll();
List<Account> findByUid(Integer uid);
User持久层映射配置
<resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型 select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称) column 是用于指定使用哪个字段的值作为条件查询 -->
<collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findByUid" column="id">
</collection>
</resultMap>
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select * from user
</select>
标签: 用于加载关联的集合对象
标签:用于指定查询account列表的sql语句,填写该sql映射的id
用于指定select属性的sql语句的参数来源,上面的参数来自user的id列,所以写成id这一个字段名。
编写账户持久层映射配置
<!-- 根据用户 id 查询账户信息 -->
<select id="findByUid" resultType="account" parameterType="int">
select * from account where uid = #{uid}
</select>
编写测试类只加载用户信息
@Test
public void testFindAll() {
//6.执行操作
List<User> users = userDao.findAll();
}