MyBatis延迟加载与立即加载案例教程
MyBatis入门-延迟加载与立即加载
加载策略
延迟加载
延迟加载(lazy load)是(也称为懒加载)Hibernate3关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。延迟加载,可以简单理解为,只有在使用的时候,才会发出sql语句进行查询。
需要在主配置文件开启加载策略,子配置文件使用collection属性
立即加载
所谓立即加载就是查询时,所有的相关数据一次被读取出来,而不是分N次。
一对一实现理解加载——查询账户可查出用户信息(在查询账户是绑定查询用户信息的方法)
一对多实现延迟加载——查询用户可查出所以账户信息(在查询用户是绑定查询账户信息的方法)
基础数据
实体类
public class User implements Serializable { /** * Java实体类为什么要实现Serializable接口 * 1.用于序列化与反序列化--一个类只有实现了Serializable接口,它的对象才能被序列化。 * 2.Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可。 */ private Integer id; private String username; private Date birthday; private String sex; private String address; //一对多关系映射:主表实体应该包含从表实体的集合引用 private List<Account> accounts; @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } public class Account implements Serializable { private Integer id; private Integer uid; private Double money; //一对一的关系中 //从表实体应该包含一个主表实体的对象引用 private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + '}'; } }
dao层的两个接口
/** * @Author: Promsing * @Date: 2021/4/4 - 16:21 * @Description: 描述 形容 * @version: 1.0 */ public interface IUserDao { /** * 查询所有 * @return */ List<User> findAll(); /** * 根据id查询 * @param i * @return */ User findById(Integer i); } public interface IAccountDao { /** * 查询所有账户,同时还有获取当前账户所属的用户信息 * @return */ List<Account> findAll(); /** * 根据用户id查询 * @param i * @return */ Account findById(Integer i); }
resource下的主映射文件与子映射文件
主:SqlMapConfig_anno.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--myBatis的主配置文件 --> <configuration> <settings> <!--开启mybatis支持延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings> <!--配置环境--> <environments default="mysql"> <!--配置mysql环境--> <environment id="mysql"> <!--配置事务的类型--> <transactionManager type="JDBC"></transactionManager> <!--配置数据源(连接池)--> <dataSource type="POOLED"> <!--配置连接数据库的基本信息--> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/eesy"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--映射文件 配置文件方式--> <mappers> <mapper resource="com/dynamic_annotation/dao/IAccountDao.xml"></mapper> <mapper resource="com/dynamic_annotation/dao/IUserDao.xml"></mapper> </mappers> <!--映射文件 注解方式(使用注解就要删除源配置文件)--> <!-- <mappers> <mapper class="com.dynamic_basics.dao.IUserDao"></mapper> </mappers>--> </configuration>
子: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.dynamic_annotation.dao.IAccountDao"> <!--定义封装account和user的resultMap--> <resultMap id="accountUserMap" type="com.dynamic_annotation.domain.Account"> <id property="id" column="id"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!--立即加载--> <!--使用select属性,使用其他DAO层的方法--> <association property="user" column="uid" javaType="com.dynamic_annotation.domain.User" select="com.dynamic_annotation.dao.IUserDao.findById"> </association> </resultMap> <!--查询所有 id使用方法名--> <select id="findAll" resultMap="accountUserMap"> select * from Account </select> <!--单个查询--> <select id="findById" parameterType="int" resultType="com.dynamic_annotation.domain.Account"> select * from Account where uid=#{id} </select> </mapper>
子: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.dynamic_annotation.dao.IUserDao"> <!--定义封装account和user的resultMap--> <resultMap id="userAccountMap" type="com.dynamic_annotation.domain.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> <!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型 select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称) column 是用于指定使用哪个字段的值作为条件查询 --> <!--延迟加载--> <collection property="accounts" ofType="com.dynamic_annotation.domain.Account" select="com.dynamic_annotation.dao.IAccountDao.findById" column="id"></collection> </resultMap> <!--查询所有 id使用方法名--> <select id="findAll" resultMap="userAccountMap"> select * from User </select> <!--根据id查询--> <select id="findById" parameterType="int" resultType="com.dynamic_annotation.domain.User"> select * from user where id=#{id} </select> </mapper>
测试类
public class AnnotationTest { private InputStream in; private SqlSession sqlSession; private IAccountDao accountDao; private IUserDao userDao; @Before public void init()throws Exception{ //1.读取配置文件 Resources是myBatis封装的类 in= Resources.getResourceAsStream("SqlMapConfig_anno.xml"); //2.创建SQLSessionFactory工厂 // SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(is); SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); SqlSessionFactory factory=builder.build(in); //3.使用工厂生产SQLSession对象 sqlSession = factory.openSession(); //4.使用SQLSession创建DAO接口的代理对象 accountDao = sqlSession.getMapper(IAccountDao.class); userDao=sqlSession.getMapper(IUserDao.class); } @After public void destroy()throws Exception{ //6.释放资源 //提交事务 sqlSession.commit(); sqlSession.close(); in.close(); } //入门案例 @Test public void testFindAllAccount(){ List<Account> accounts = accountDao.findAll(); System.out.println("------每个account的信息------"); for (Account account : accounts) { System.out.println(account); System.out.println(account.getUser()); } } @Test public void testFindAccount(){ Account account = accountDao.findById(46); System.out.println(account); } @Test public void testFindAllUser(){ List<User> users = userDao.findAll(); for (User user : users) { System.out.println(user); System.out.println(user.getAccounts()); } } @Test public void testFindUser(){ User user = userDao.findById(49); System.out.println(user); } }
到此这篇关于MyBatis延迟加载与立即加载案例教程的文章就介绍到这了,更多相关MyBatis延迟加载与立即加载内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
赞 (0)