查询订单表的时候,可以关联查出订单的详情,也可以需要订单详情的时候,再去订单详情表查询。前者对应的就是立即加载,后者对应的就是懒加载。
延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)
立即加载:不管用不用,只要一调用方法,马上发起查询。
举例前的数据准备
dao层:
IUserDao:
/**
* 用户的持久层接口
*/
public interface IUserDao {
//同时获取用户的所用账户
List<User> findAll();
User findUserById(Integer id);
}
IAccountDao:
public interface IAccountDao {
List<Account> findAll();
//查询所有账户,包含对应的用户名称和地址-通过写account的子类方式查询
List<AccountUser> findAllAccount();
}
domain层:
Account:
public class Account implements Serializable {
//windows下的mysql 和 实体对应不区分大小写
private Integer id;
private Integer uid;
private Double money;
//一对一
private User user;
//生成getter()和setter()、toString()
}
User :
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多
private List<Account> accounts;
//生成getter()和setter()、toString()
}
查询用户以及该用户下的所用账户
IUserDao.xml
<mapper namespace="cn.ith.dao.IUserDao">
<resultMap id="userAccountMap" type="user">
<id property="id" column="id">id>
<result property="username" column="username">result>
<result property="birthday" column="birthday">result>
<result property="sex" column="sex">result>
<result property="address" column="address">result>
<collection property="accounts" ofType="account">
<id property="id" column="aid">id>
<result property="uid" column="uid">result>
<result property="money" column="money">result>
collection>
resultMap>
<select id="findAll" resultMap="userAccountMap">
select a.id as aid, a.uid, a.money, u.* from `user` u left join account a on u.id=a.uid
select>
mapper>
测试类:
public class IAccountDaoTest {
private InputStream in;
private SqlSession session;
private IAccountDao accountDao;
@Before
public void init() throws IOException {
//1读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3使用工厂生产SqlSession对象
session = factory.openSession();
//4使用SqlSession创建Dao接口的代理对象
accountDao = session.getMapper(IAccountDao.class);
}
@After
public void destory() throws IOException {
session.commit();
//6释放资源
session.close();
in.close();
}
@Test
public void findAll(){
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
List<Account> accounts = user.getAccounts();
for (Account account : accounts) {
System.out.println(account);
}
System.out.println("-----------------------");
}
}
}
在MyBatis的主配置文件中,一般是SqlMapConfig.xml文件,加入如下配置:
<configuration>
......
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
......
configuration>
<mapper namespace="cn.ith.dao.IAccountDao">
<resultMap id="accountUserMap" type="account">
<id property="id" column="id">id>
<result property="uid" column="uid">result>
<result property="money" column="money">result>
<association property="user" column="uid" javaType="user" select="cn.ith.dao.IUserDao.findUserById">
association>
resultMap>
<select id="findAll" resultMap="accountUserMap">
SELECT * FROM account
select>
<select id="findAccountByUid" resultType="account">
select * from account where uid = #{uid}
select>
mapper>
IUserDao.xml
<mapper namespace="cn.ith.dao.IUserDao">
<resultMap id="userAccountMap" type="user">
<id property="id" column="id">id>
<result property="username" column="username">result>
<result property="birthday" column="birthday">result>
<result property="sex" column="sex">result>
<result property="address" column="address">result>
<collection property="accounts" column="id" ofType="account" select="cn.ith.dao.IAccountDao.findAccountByUid">
collection>
resultMap>
<select id="findAll" resultMap="userAccountMap">
select * from user
select>
<select id="findUserById" parameterType="Integer" resultType="user">
select * from user where id=#{id}
select>
mapper>
测试,当只需要用户信息的时候,只执行了select * from user
public class IAccountDaoTest {
private InputStream in;
private SqlSession session;
private IAccountDao accountDao;
@Before
public void init() throws IOException {
//1读取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3使用工厂生产SqlSession对象
session = factory.openSession();
//4使用SqlSession创建Dao接口的代理对象
accountDao = session.getMapper(IAccountDao.class);
}
@After
public void destory() throws IOException {
session.commit();
//6释放资源
session.close();
in.close();
}
@Test
public void findAll(){
List<User> users = userDao.findAll();
}
}
测试,当需要用户下的账户信息的时候,又去分别执行了select * from account where uid = ?
@Test
public void findAll(){
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
List<Account> accounts = user.getAccounts();
for (Account account : accounts) {
System.out.println(account);
}
System.out.println("-----------------------");
}
}