MyBatis立即加载和延迟加载

查询订单表的时候,可以关联查出订单的详情,也可以需要订单详情的时候,再去订单详情表查询。前者对应的就是立即加载,后者对应的就是懒加载。

延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)

立即加载:不管用不用,只要一调用方法,马上发起查询。

举例前的数据准备
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立即加载和延迟加载_第1张图片

延迟加载

在MyBatis的主配置文件中,一般是SqlMapConfig.xml文件,加入如下配置:

<configuration>
	......
    <settings>
        
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    settings>
    ......
configuration>

在这里插入图片描述
IAccountDao.xml

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

MyBatis立即加载和延迟加载_第2张图片
测试,当需要用户下的账户信息的时候,又去分别执行了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("-----------------------");
    }
}

MyBatis立即加载和延迟加载_第3张图片

你可能感兴趣的:(Java,#,MyBatis)