Mybatis延迟加载之:多对一(使用assocation实现)

Java 1104℃

延迟加载:也称懒加载,就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。可以提高数据库性能。Mybatis在进行多表操作时,使用resultMap来实现,其中通过association实现一对一和多对一映射、通过collection实现一对多和多对多映射。association、collection都具备延迟加载功能,本文演示association的延迟加载。

1.准备工作

创建maven、添加jar包坐标、MyBatis主配置文件、log4j的配置文件等准备工作可以参考:IDEA中Maven工程的MyBatis快速入门

在MyBatis主配置文件中开启延时加载,需要在<configuration>标签中增加:

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

2.编写实体类

假如数据库有user表和account表,sql语句为:

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`sex` char(1) default NULL COMMENT '性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `user`(`id`,`username`,`sex`) values (41,'老王','男'),(42,'小二王','女'),(43,'小三王','女');
DROP TABLE IF EXISTS `account`;

CREATE TABLE `account` (
`id` int(11) NOT NULL COMMENT '编号',
`uid` int(11) default NULL COMMENT '用户编号',
`money` double default NULL COMMENT '金额',
PRIMARY KEY (`id`),
CONSTRAINT `FK_Reference_1` FOREIGN KEY (`uid`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert into `account`(`id`,`uid`,`money`) values (1,41,1000),(2,42,1000),(3,42,2000);

在src/main/java下创建User类和Account类,实现Serializable接口,且要求与数据表有对应的属性名,代码可参考:IDEA中Maven工程的MyBatis快速入门

可以在Account类中加入一个User类的属性来代表这个用户有哪些账户。即需要在Account.class中添加如下代码:

private User user;

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

3.编写实体类的持久层映射接口

这里对应的User类持久层映射接口取名UserMapper,放在src/main/java下,代码如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.QueryVo;
import com.gqzzw.domain.User;

import java.util.List;

public interface UserMapper {
    //根据id查询用户
    List<User> findById(int id);
}

Account类持久层映射接口取名AccountMapper,放在src/main/java下,代码如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.Account;

import java.util.List;

public interface AccountMapper {
    //多对一查询
    List<Account> findAll();
}

4.编写映射接口的配置文件

放在src/main/resources下,必须与久层接口包路径和文件名相同,即:com.gqzzw.mapper.UserMapper.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.gqzzw.mapper.UserMapper">
    <!--  根据id查询用户  -->
    <select id="findById" resultType="com.gqzzw.domain.User" parameterType="int">
        select * from user where id=#{id};
    </select>
</mapper>

放在src/main/resources下,必须与久层接口包路径和文件名相同,即:com.gqzzw.mapper.AccountMapper.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.gqzzw.mapper.AccountMapper">
    <!--  根据Uid查询账户  -->
    <select id="findByUid" resultType="com.gqzzw.domain.Account" parameterType="int">
        select * from account where uid=#{uid}
    </select>
    <!--  多对一查询  -->
    <resultMap id="account_user" type="com.gqzzw.domain.Account">
        <id column="id" property="id"/>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <association property="user" javaType="com.gqzzw.domain.User"
                     select="com.gqzzw.mapper.UserMapper.findById" column="uid"/>
    </resultMap>
    <select id="findAll" resultMap="account_user">
        select * from account
    </select>
</mapper>

5.编写测试类

放在src/test/java下,编写测试类,内容如下:

package com.gqzzw.mapper;

import com.gqzzw.domain.Account;
import com.gqzzw.domain.User;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class AccountMapperTset {
    private InputStream in;
    private SqlSession sqlSession;
    private AccountMapper accountMapper;

    @Before
    public void init() throws IOException {
        //读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //使用构建者创建工厂对象SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //使用SqlSessionFactory产SqlSession对象生
        sqlSession = factory.openSession();
        //产SqlSession对象时可以传true代表自动提交事务
        //sqlSession = factory.openSession(true);
        //使用SqlSession创建映射接口的代理对象
        accountMapper = sqlSession.getMapper(AccountMapper.class);
    }

    @After
    public void destroy() throws IOException {
        //提交事务,释放资源
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    @Test
    //多对一查询
    public void findAll(){
        List<Account> accounts = accountMapper.findAll();
//        for (Account account : accounts) {
//            System.out.println(account.getUser());
//        }
    }

}

转载请注明:零五宝典 » Mybatis延迟加载之:多对一(使用assocation实现)