MyBatis关联查询的实现
目录
- 前言
- 关联查询
- 附
- 懒加载
- 对象为集合时的关联查询
前言
在 MyBATis:配置文件 文章中,最后介绍了可以使用 select 标签的 resultMap 属性实现关联查询,下面简单示例
关联查询
首先,先创建 association_role 和 association_user 两张数据表,并建立关联关系
表结构如图:表信息如图:
在创建 association_user 表时需要添加 association_role 表的关联字段( role_id )
表结构如图:
表信息如图:
接着,创建与两张数据表一一映射的实体类 AssociationRole 和 AssociationUser
// AssociationRole package cn.edu.MyBatisDemo.model; public class AssociationRole { private int id; private String role; public AssociationRole() { super(); } public AssociationRole(int id, String role) { this.id = id; this.role = role; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } @Override public String toString() { return "AssociationRole{" + "id=" + id + ", role='" + role + '\'' + '}'; } }
// AssociationUser package cn.edu.MyBatisDemo.model; public class AssociationUser { private int id; private String name; //添加 AssociationRole 属性 private AssociationRole role; // AssociationRole -- 1:m -- AssociationUser (一对多关系) public AssociationUser(int id, String name, AssociationRole role) { this.id = id; this.name = name; this.role = role; } public AssociationUser() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public AssociationRole getRole() { return role; } public void setRole(AssociationRole role) { this.role = role; } @Override public String toString() { return "AssociationUser{" + "id=" + id + ", name='" + name + '\'' + ", role=" + role + '}'; } }
然后,创建一个接口 AssociationUserMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationUserMap.XML 实现接口方法
// 接口 AssociationUserMap package cn.edu.MyBatisDemo.mapper; import cn.edu.MyBatisDemo.model.AssociationUser; public interface AssociationUserMap { public AssociationUser selectUserById(int id); // 获取指定用户的信息 }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 映射文件 AssociationUserMap.xml --> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"> <select id="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 指定类 --> <resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" > <!-- 字段名对应的属性名 --> <id column="id" property="id" /> <result column="name" property="name" /> <!-- 映射关联对象的属性 --> <result column="role_id" property="role.id" /> <result column="role" property="role.role" /> </resultMap> </mapper>
最后,测试结果
package cn.edu.MyBatisDemo.test; import cn.edu.MyBatisDemo.mapper.AssociationUserMap; import cn.edu.MyBatisDemo.model.AssociationUser; 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.Test; import Java.io.IOException; import java.io.InputStream; public class AssociationTest { @Test public void test() throws IOException { //1.根据配置文件创建数据库连接会话的工厂类 InputStream inputStream = Resources.getResourceAsStream("mybatis.xml"); //获取工厂类 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().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 标签实现分步关联查询,再进行配置懒加载首先,再创建一个接口 AssociationRwww.devze.comoleMap ,声明获取指定用户信息的方法。同时,创建映射文件 AssociationRoleMap.xml 实现接口方法
package cn.edu.MyBatisDemo.mapper; import cn.edu.MyBatisDemo.model.AssociationRole; public interface AssociationRoleMap { public AssociationRole selectRoleById(int id); // 获取指定用户的信息 }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationRoleMap"> <select id="selectRoleById" resultType="associationRole"> SELECT `id`,`role` FROM `association_role` WHERE `id`=#{id} </select> </mapper>
接着,在映射文件 AssociationUserMap.xml 中,使用 association 标签实现关联查询。同时,修改 select 标签上的 SQL 语句
<?xml version="1.0" encoding=android"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.edu.MyBatisDemo.mapper.AssociationUserMap"> <select id="selectUserById" resultMap="associationUser"> <!-- 对比:分步关联查询的 SQL 语句相对简单些 --> SELECT `id`,`name`,`role_id` FROM `association_user` WHERE `id`=#{id} </select> <!-- id 设置别名;type 指定类 --> <resultMap id="associationUser" type="cn.edu.MyBatisDemo.model.AssociationUser" > <!-- 字段名对应的属性名 --> android <id column="id" property="id" /> <result column="name" property="name" /> &javascriptlt;!-- 映射关联对象的属性 --> <!-- <result column="role_id" property="role.id" /> --> <!-- <result column="role" property="role.role" /> --> <!-- 也可以使用子标签 association 实现关联查询 --> <!-- property = 添加 AssociationRole 属性 role ;select = 关联对象映射文件中的方法 id ;column = 外键 --> <association property="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.ConsoleAppeFCyCLsWXEtnder 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> <setting name="LazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
最后,测试结果
1.只获取 association_user 中的 name 属性(只加载所需要的数据,其他数据不加载)
查看日志,结果如图:
2.分步关联查询(加载所有关联数据)
查看日志,结果如图:
对象为集合时的关联查询
当关联查询的对象为集合时,与上面案例的主要区别为使用的是 collection 标签,而不是 association 标签。
简单示例:
首先,在实体类 AssociationRole 中添加 users 属性
接着,分别在接口 AssociationUserMap 和 AssociationRoleMap 中添加相应的方法
然后,分别在映射文件 AssociationUserMap.xml 和 AssociationRoleMap.xml 中实现相应的方法。同时在 AssociationRoleMap.xml 配置关联映射
最后,测试结果
结果如图:
到此这篇关于MyBatis关联查询的实现的文章就介绍到这了,更多相关MyBatis关联查询内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论