Mybatis09_一对一、一对多、多对多、延迟加载

(1)查询:

1、 一对一 查询

查询user表及其对应的account表的数据

方式一: 利用继承的方式来解决(不常用)

(继承了某一类的全部基本属性,在该类中就有了数据库所对应的字段)

实体类:
在这里插入图片描述

用于查询的实体类:

(继承了Account类,就有了account表要对应的属性)

在这里插入图片描述

映射文件:(查询user表和account表)

要查询的信息为user表和account表中对应的信息,写一个类,里面有account表中的属性,
在继承user类,该类中就有了user表和account表中的所有属性

查询结果会根据  查询数据库的结果的字段名  和  映射类的类名对应
<!--一对一表,使用继承的方式进行封装(不常用)-->
<select id="findAllAccountUsers" resultType="com.zy.domain.AccountUser2">
    select  *  from account,user where user.id = account.uid;
</select>

测试方法:

public static void main(String[] args) throws IOException {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IAccountDao iAccountDao = sqlSession.getMapper(IAccountDao.class);
   List<AccountUser2> all = iAccountDao.findAllAccountUsers();
   for (AccountUser2 account : all) {
      System.out.println(account.toString());
   }
   sqlSession.close();
   in.close();
}

方式二:利用映射文件的重新指定封装类对应的每一个数据库列表值(常用)

封装的实体类:
在这里插入图片描述

映射文件:

在这里插入图片描述

2、 一对多 的查询

​需求:
​		查询所有用户信息及用户关联的账户信息。(user表和account表进行关联)
分析:
​	   用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,
	   此时也要将用户信息查询出来,我们想到了左外连接查询比较合适。

建立存放数据的实体类:userList

一个user里面对应着里面有多个用户Account

在这里插入图片描述

映射文件信息:

实体类中的每一个字段,对应着查询到的数据中的哪一个字段??

在这里插入图片描述

测试类

public static void main(String[] args) throws Exception {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
   List<UserList> all = iUserDao.findUserListAll();
   for (UserList temp:all) {
      System.out.println(temp.toString());
   }
}

3、多对多的查询:

​实例:用户和角色(就相当于两个一对多)

​		一个用户可以对应多个角色

​		一个角色可以对应对个用户

步骤:

​	1、建立两张表:用户表,角色表
​			    让用户表和角色表具有多对多的关系。
				需要使用中间表,中间表中包用户表和角色表的关系
				
​	2、建立两个实体类:用户实体类和角色实体类
​				让用户和角色的实体类能体现出来多对多的关系
​					(各自实体类包含对方一个集合引用)

​	3、建立两个配置文件
​				用户的配置文件
​				角色的配置文件

​	4、实现配置:
​				当我们查询用户时,可以同时得到用户所包含的角色信息
​				当我们查询角色时,可以同时得到角色的所赋予的用户信息

在这里插入图片描述

(可以看出一个user可能对应着两个角色,一个角色可能对应着两个user)

一个User对应多个Role

​实体类:
在这里插入图片描述

映射文件:

<resultMap id="UserRoleMap" type="com.zy.domain.UserRoleList">
    <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="roles" ofType="com.zy.domain.UserRoleList">
        <id property="roleId" column="id"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
    </collection>
</resultMap>

<select id="findYYY" resultMap="UserRoleMap">
    SELECT
    u.*,
    r.id as rid,
    r.role_name ,
    u.role_desc
FROM
    ROLE u
        INNER JOIN
    USER_ROLE ur
    ON ( u.id = ur.uid)
        INNER JOIN
    role r
    ON (r.id = ur.rid);
</select>

测试方法:

public static void main(String[] args) throws IOException {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
   List<UserRoleList> all = iUserDao.findYYY();
   for (UserRoleList temp:all) {
      System.out.println(temp.toString());
   }
}

一个Role对应多个user

	和上面类似,相当于写一个一对多,
	一个Role中有一个user集合
	在配置配置文件即可


(2)、 Mybatis的延迟加载:

1、什么叫延迟加载??

​就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。

延迟加载也称懒加载.按需加载

2、 什么叫立即加载??

不管用不用数据,只要方法被调用,马上发起查询

3、延迟加载的好处与坏处:

好处:
		先从单表查询,需要时再从关联表去关联查询(一次性查出来,太浪费空间),
		大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

坏处 :
		因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,
		因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。

4、经常 什么时候采用延迟加载?

关系表中有四种关系: 一对一      一对多    多对一    多对多

当关系为: 一对多    多对多(相当于一对多)  总而言之对应的多个的时候进行延迟加载

为什么对应多个的时候进行延迟加载??

​	延迟查询可以做到:  先从单表中查询,需要时在从关联表中关联查询对应的多条数据,
				       这样大大提高了数据库的性能。

5、什么时候采用立即加载?

​关系表中有四种关系: 一对一      一对多    多对一    多对多
	
​当关系为: 一对一    多对一(相当于一对一) 总而言之对应的一个的时候进行立即加载
	
	为什么对应一个的时候进行立即加载??
			立即查询可以做到: 一条只对应一条,直接加载出来就完成了

6、使用 assocation 标签 实现延迟加载

​	一对一进行的延迟加载:

​			第一步:写响应的接口

​			第二步:IAccountDao.xml 映射配置文件:
<mapper namespace="com.zy.Dao.IAccountDao">
        <resultMap type="com.zy.domain.AccountUserList" id="accountUserListMap">
            <id column="aid" property="id"/>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
            <!--association标签:处理单一的关联对象 处理单一属性的关联关系 -->
            <!-- javaType属性:该属性的类型是什么-->
            <!-- 根据什么方法进行进一步查询   IUserDao接口中的findById的方法  该方法需要一个id传入uid(uid相当于是两张表有联系的键)-->
            <!-- select属性:发送哪一条sql语句-->
            <!-- column属性:用哪个列的值作为条件去查询关联的对象,我们要传递给 select 映射的参数-->
            <association property="user" javaType="com.zy.domain.User" select="com.zy.Dao.IUserDao.findById" column="uid"></association>
        </resultMap>

        <select id="findAccountUserList" resultMap="accountUserListMap">
            <!-- 为什么关联查询,只写个就可以了??不需要子查询??-->
            <!-- 应为在上面的映射关系中就可以进行进一步通过uid对user表进行查询-->
            select * from account
       </select>
</mapper>
​					指向的IUserDao接口的findById方法已经写好

​			第三步:在主配置文件中开启延迟配置(详细去看Mybatis官方文档)
<!-- 配置参数 -->
<settings>
    <!--打开延迟加载的开关 ,当开启时,所有关联对象都会延迟加载-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载-->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  带延迟的和不带延迟的分别调用测试方法发现:

​			不带延迟的立马查询    带延迟没有立刻查询

在这里插入图片描述

7、使用 Collection 标签 实现延迟加载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小镇男孩~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值