0


MyBatis:关联查询

MyBatis

在这里插入图片描述

前言

MyBatis:配置文件 文章中,最后介绍了可以使用 select 标签的 resultMap 属性实现关联查询,下面简单示例

关联查询

首先,先创建 association_role 和 association_user 两张数据表,并建立关联关系
表结构如图:
在这里插入图片描述
表信息如图:
在这里插入图片描述

在创建 association_user 表时需要添加 association_role 表的关联字段( role_id )
表结构如图:
在这里插入图片描述
表信息如图:
在这里插入图片描述

接着,创建与两张数据表一一映射的实体类 AssociationRole 和 AssociationUser

// AssociationRolepackagecn.edu.MyBatisDemo.model;publicclassAssociationRole{privateint id;privateString role;publicAssociationRole(){super();}publicAssociationRole(int id,String role){this.id = id;this.role = role;}publicintgetId(){return id;}publicvoidsetId(int id){this.id = id;}publicStringgetRole(){return role;}publicvoidsetRole(String role){this.role = role;}@OverridepublicStringtoString(){return"AssociationRole{"+"id="+ id +", role='"+ role +'\''+'}';}}
// AssociationUserpackagecn.edu.MyBatisDemo.model;publicclassAssociationUser{privateint id;privateString name;//添加 AssociationRole 属性privateAssociationRole role;// AssociationRole -- 1:m -- AssociationUser (一对多关系)publicAssociationUser(int id,String name,AssociationRole role){this.id = id;this.name = name;this.role = role;}publicAssociationUser(){super();}publicintgetId(){return id;}publicvoidsetId(int id){this.id = id;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicAssociationRolegetRole(){return role;}publicvoidsetRole(AssociationRole role){this.role = role;}@OverridepublicStringtoString(){return"AssociationUser{"+"id="+ id +", name='"+ name +'\''+", role="+ role +'}';}}

然后,创建一个接口 AssociationUserMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationUserMap.xml 实现接口方法

// 接口 AssociationUserMappackagecn.edu.MyBatisDemo.mapper;importcn.edu.MyBatisDemo.model.AssociationUser;publicinterfaceAssociationUserMap{publicAssociationUserselectUserById(int id);// 获取指定用户的信息}
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 映射文件 AssociationUserMap.xml --><mappernamespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"><selectid="selectUserById"resultMap="associationUser">
        SELECT user.id,user.name,user.role_id,role.role
            FROM association_user USER,`association_role` role
                WHERE user.role_id=role.id AND user.id=#{id}
    </select><!-- id 设置别名;type 指定类 --><resultMapid="associationUser"type="cn.edu.MyBatisDemo.model.AssociationUser"><!-- 字段名对应的属性名 --><idcolumn="id"property="id"/><resultcolumn="name"property="name"/><!-- 映射关联对象的属性 --><resultcolumn="role_id"property="role.id"/><resultcolumn="role"property="role.role"/></resultMap></mapper>

最后,测试结果

packagecn.edu.MyBatisDemo.test;importcn.edu.MyBatisDemo.mapper.AssociationUserMap;importcn.edu.MyBatisDemo.model.AssociationUser;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.apache.ibatis.session.SqlSessionFactoryBuilder;importorg.junit.Test;importjava.io.IOException;importjava.io.InputStream;publicclassAssociationTest{@Testpublicvoidtest()throwsIOException{//1.根据配置文件创建数据库连接会话的工厂类InputStream inputStream =Resources.getResourceAsStream("mybatis.xml");//获取工厂类SqlSessionFactory sqlSessionFactory =newSqlSessionFactoryBuilder().build(inputStream);//2.通过工厂类获取数据库连接的会话SqlSession sqlSession = sqlSessionFactory.openSession();//3.通过 sqlSession 操作数据库try{AssociationUserMap userMap = sqlSession.getMapper(AssociationUserMap.class);//获取所有用户AssociationUser user = userMap.selectUserById(20230829);System.out.println(user);
            sqlSession.commit();}finally{
            sqlSession.close();}}}

结果如图:
在这里插入图片描述

懒加载

懒加载( Lazy Loading ),是在使用所需数据时才进行加载,而不是直接加载所有关联数据。这有利于提高查询性能和减少资源消耗。当一个实体类中包含关联对象(如一对多、多对多关系)时,使用懒加载可以避免在查询主对象时立即加载所有关联对象的数据,而是等到真正需要访问关联对象时才进行加载。

简单示例:
在上面案例的基础上,先通过使用 association 标签实现分步关联查询,再进行配置懒加载

首先,再创建一个接口 AssociationRoleMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationRoleMap.xml 实现接口方法

packagecn.edu.MyBatisDemo.mapper;importcn.edu.MyBatisDemo.model.AssociationRole;publicinterfaceAssociationRoleMap{publicAssociationRoleselectRoleById(int id);// 获取指定用户的信息}
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="cn.edu.MyBatisDemo.mapper.AssociationRoleMap"><selectid="selectRoleById"resultType="associationRole">
        SELECT `id`,`role` FROM `association_role` WHERE `id`=#{id}
    </select></mapper>

接着,在映射文件 AssociationUserMap.xml 中,使用 association 标签实现关联查询。同时,修改 select 标签上的 SQL 语句

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"><selectid="selectUserById"resultMap="associationUser"><!-- 对比:分步关联查询的 SQL 语句相对简单些 -->
        SELECT `id`,`name`,`role_id` FROM `association_user` WHERE `id`=#{id}
    </select><!-- id 设置别名;type 指定类 --><resultMapid="associationUser"type="cn.edu.MyBatisDemo.model.AssociationUser"><!-- 字段名对应的属性名 --><idcolumn="id"property="id"/><resultcolumn="name"property="name"/><!-- 映射关联对象的属性 --><!-- <result column="role_id" property="role.id" /> --><!-- <result column="role" property="role.role" /> --><!-- 也可以使用子标签 association 实现关联查询 --><!-- property = 添加 AssociationRole 属性 role ;select = 关联对象映射文件中的方法 id ;column = 外键 --><associationproperty="role"select="cn.edu.MyBatisDemo.mapper.AssociationRoleMap.selectRoleById"column="role_id"></association></resultMap></mapper>

然后,在 pom.xml 配置文件中添加依赖包。同时,在 resources 目录下创建 log4j.properties 资源文件。目的是生成日志文件,方便观察理解

<!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency>
#日志级别,分为八个级别( Off-关闭日志记录 > Fatal-严重错误 > Error-错误 > Warn-警告 > Info-运行信息 > Debug-调试 > Trace-低级信息 > All-所有日志记录)
#日志级别越高,过滤的信息越多

#配置根节点
log4j.rootLogger=Debug,stdout,D
#配置控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.Threshold=Error
##输出格式(%d %p [%1] %m %n——日期时间 类 路径 信息 换行)
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%l] %m %n

#配置文件输出
log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.Append=true
log4j.appender.D.File=./log4j.log
log4j.appender.D.Threshold=Debug
#输出格式
log4j.appender.D.layout=org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d %p [%l] %m %n

随之,在 resources 目录下的 mybatis.xml 全局配置文件中进行配置懒加载

<!-- 懒加载配置 --><settings><settingname="LazyLoadingEnabled"value="true"/><settingname="aggressiveLazyLoading"value="false"/></settings>

最后,测试结果
1.只获取 association_user 中的 name 属性(只加载所需要的数据,其他数据不加载)
在这里插入图片描述
查看日志,结果如图:
在这里插入图片描述

2.分步关联查询(加载所有关联数据)
在这里插入图片描述
查看日志,结果如图:
在这里插入图片描述

对象为集合时的关联查询

当关联查询的对象为集合时,与上面案例的主要区别为使用的是 collection 标签,而不是 association 标签。

简单示例:
首先,在实体类 AssociationRole 中添加 users 属性
在这里插入图片描述

接着,分别在接口 AssociationUserMap 和 AssociationRoleMap 中添加相应的方法
在这里插入图片描述
在这里插入图片描述

然后,分别在映射文件 AssociationUserMap.xml 和 AssociationRoleMap.xml 中实现相应的方法。同时在 AssociationRoleMap.xml 配置关联映射
在这里插入图片描述
在这里插入图片描述

最后,测试结果
结果如图:
在这里插入图片描述


本文转载自: https://blog.csdn.net/qq_56886142/article/details/132452975
版权归原作者 啊Q老师 所有, 如有侵权,请联系我们删除。

“MyBatis:关联查询”的评论:

还没有评论