mybatis多表映射-延迟加载,延迟加载的前提条件是:分步查询

2023-12-12 05:52

本文主要是介绍mybatis多表映射-延迟加载,延迟加载的前提条件是:分步查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、建库建表

create database `mybatis-example`;
use `mybatis-example`;
create table t_book
(bid   varchar(20) primary key,bname varchar(20),stuid varchar(20)
);
insert into t_book values('b001','Java','s001');
insert into t_book values('b002','Python','s002');
insert into t_book values('b003','C++','s003');
insert into t_book values('b004','PHP','s003');
create table t_stu(sid varchar(20)  primary key,sname varchar(20)
);
insert into t_stu values('s001','张三');
insert into t_stu values('s002','李四');
insert into t_stu values('s003','王五');
alter table t_bookadd constraint fk_book_stuid foreign key (stuid) references t_stu (sid);

2、pom.xml

    <dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><!-- MySQL驱动 mybatis底层依赖jdbc驱动实现,本次不需要导入连接池,mybatis自带! --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--junit5测试--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- 日志 , 会自动传递slf4j门面--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId></dependency></dependencies>

3、Stu.java

package com.atguigu.mybatis.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Stu {private String sid;private String sname;//对多:一个学员拥有多本图书private List<Book> bookList;
}

4、Book.java

package com.atguigu.mybatis.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {private String bid;private String bname;private String stuid;//对一关联:一本图书属于一个学员private Stu stu;
}

5、mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 具体配置 --><!-- 从org.apache.ibatis.session.Configuration类中可以查看能使用的配置项 --><!-- 将mapUnderscoreToCamelCase属性配置为true,表示开启自动映射驼峰式命名规则 --><!-- 规则要求数据库表字段命名方式:单词_单词 --><!-- 规则要求Java实体类属性名命名方式:首字母小写的驼峰式命名 --><settings><setting name="lazyLoadingEnabled" value="true"/><setting name="autoMappingBehavior" value="FULL"/><setting name="mapUnderscoreToCamelCase" value="true"/></settings><typeAliases><!--<typeAlias type="com.atguigu.mybatis.pojo.Employee" alias="emp"/>--><package name="com.atguigu.mybatis.pojo"/></typeAliases><!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 --><environments default="development"><!-- environment表示配置Mybatis的一个具体的环境 --><environment id="development"><!-- Mybatis的内置的事务管理器 --><transactionManager type="JDBC"/><!-- 配置数据源 --><dataSource type="POOLED"><!-- 建立数据库连接的具体信息 --><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><!-- Mapper注册:指定Mybatis映射文件的具体位置 --><!-- mapper标签:配置一个具体的Mapper映射文件 --><!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 --><!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 --><mapper resource="mappers/StuMapper.xml"/><mapper resource="mappers/BookMapper.xml"/></mappers></configuration>

6、StuMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.atguigu.mybatis.mapper.StuMapper"><select id="getStuList" resultType="Stu">select * from t_stu</select><select id="getStuListWithBookList" resultMap="StuWithBookListResultMap">select * from t_stu t1 inner join t_book t2 on t1.sid=t2.stuid</select><resultMap id="StuWithBookListResultMap" type="Stu"><id property="sid" column="sid"/><!--<result property="sname" column="sname"/>--><!--对多关联--><collection property="bookList" ofType="Book"><id property="bid" column="bid"/><!--<result property="bname" column="bname"/>--></collection></resultMap><select id="getStuWithBookList" resultMap="StuWithBookListResultMap2">select * from t_stu where sid=#{value}</select><resultMap id="StuWithBookListResultMap2" type="Stu"><id property="sid" column="sid"/><collection property="bookList"select="com.atguigu.mybatis.mapper.BookMapper.getBookListBySid" column="sid"/></resultMap></mapper>

7、BookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace等于mapper接口类的全限定名,这样实现对应 -->
<mapper namespace="com.atguigu.mybatis.mapper.BookMapper"><select id="getBook" resultType="Book">select * from t_bookwhere bid=#{value}</select><select id="getBook2" resultMap="BookWithStuResultMap">select * from t_book t1 inner join t_stu t2 on t1.stuid=t2.sidwhere t1.bid=#{value}</select><resultMap id="BookWithStuResultMap" type="Book"><id property="bid" column="bid"/><!--<result property="bname" column="bname"/>--><!--对一关联--><association property="stu" javaType="Stu"><id property="sid" column="stuid"/><!--column或者可以写sid--><!--<result property="sname" column="sname"/>--></association></resultMap><select id="getBookListBySid" resultType="Book">select * from t_book where stuid=#{value}</select><select id="getBook3" resultType="Book">select bid,bname, sid as 'stu.sid',sname as'stu.sname'from t_book t1 inner join t_stu t2 on t1.stuid=t2.sidwhere t1.bid=#{value}</select>
</mapper>

8、logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true"><!-- 指定日志输出的位置,ConsoleAppender表示输出到控制台 --><appender name="STDOUT"class="ch.qos.logback.core.ConsoleAppender"><encoder><!-- 日志输出的格式 --><!-- 按照顺序分别是:时间、日志级别、线程名称、打印日志的类、日志主体内容、换行 --><pattern>[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n</pattern><charset>UTF-8</charset></encoder></appender><!-- 设置全局日志级别。日志级别按顺序分别是:TRACE、DEBUG、INFO、WARN、ERROR --><!-- 指定任何一个日志级别都只打印当前级别和后面级别的日志。 --><root level="DEBUG"><!-- 指定打印日志的appender,这里通过“STDOUT”引用了前面配置的appender --><appender-ref ref="STDOUT" /></root><!-- 根据特殊需求指定局部日志级别,可以是包名或全类名。 --><logger name="com.atguigu.mybatis" level="DEBUG" />
</configuration>

9、Mybatis.java

package com.atguigu.mybatis;
import com.atguigu.mybatis.mapper.StuMapper;
import com.atguigu.mybatis.pojo.Stu;
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.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
public class MybatisTest {SqlSessionFactory sqlSessionFactory;SqlSession sqlSession;StuMapper stuMapper;//BookMapper bookMapper;@BeforeEachpublic void setup() throws IOException {// 获取资源流,读取"mybatis-config.xml"文件InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");// 使用资源流创建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);// 使用SqlSessionFactory打开一个SessionsqlSession = sqlSessionFactory.openSession();//基于Mapper接口编程stuMapper = sqlSession.getMapper(StuMapper.class);//bookMapper = sqlSession.getMapper(BookMapper.class);}// 在每个测试用例之后执行的清理方法@AfterEachpublic void teardown() {sqlSession.commit();  // 提交事务sqlSession.close();  // 关闭SqlSession}@Testpublic void test01() {//stuMapper.getStuList().forEach(System.out::println);//stuMapper.getStuListWithBookList().forEach(System.out::println);//System.out.println(bookMapper.getBook("b001"));//System.out.println(bookMapper.getBook2("b002"));//System.out.println(stuMapper.getStuWithBookList("s003"));//System.out.println(bookMapper.getBook3("b001"));Stu stu = stuMapper.getStuWithBookList("s003");System.out.println(stu.getSname());//如果下面这句话不执行,则只有一条SQL语句,也就是不会查询加载book集合的 - 这种现象称之为延迟加载System.out.println(stu.getBookList().size());}
}

 10、<setting name="lazyLoadingEnabled" value="true"/>有什么作用?

  1. <setting name="lazyLoadingEnabled" value="true"/>这段代码的作用是 启用延迟加载 。在许多ORM(对象关系映射)框架中,例如Hibernate或MyBatis,这会设置为true。
  2. 当lazyLoadingEnabled设为true时,这些框架会采用延迟加载策略。这意味着 只有在需要数据的时候它们才会去数据库获取数据而不是在查询时立即加载所有数据。这种策略可以节省系统资源,特别是当处理大量数据时,因为它可以减少内存的使用和数据库查询的次数。
  3. 然而,需要注意的是,延迟加载也有其缺点。由于数据是按需加载的,因此初次加载数据时可能不会立即得到所有数据。这可能会导致在需要的时候数据还未准备好,从而影响用户体验。因此,是否应该使用延迟加载需要根据具体的应用场景和需求来决定。
  4. 这个设置的作用是开启 MyBatis 的延迟加载功能。延迟加载是指在查询父对象的过程中,只有在需要使用到子对象时才去查询子对象的数据。这样可以减少查询的数据量,提高查询的效率。对于拥有大量关联对象的实体对象,开启延迟加载功能可以有效地减少数据库查询的次数和查询的数据量,提高应用程序的性能。

  5. 这个设置是用于开启 MyBatis 的延迟加载功能。延迟加载指的是在查询数据时,只加载必要的数据而不是全部数据从而提升查询效率。例如,如果一个实体关联了很多其他实体,但是在查询时只需要其中的一部分数据,那么就可以使用延迟加载来避免不必要的数据加载和处理。

  6. 当lazyLoadingEnabled为true时,MyBatis就会在需要用到关联对象时才去加载。但这个特性需要注意一些问题,例如在关闭了session的情况下会出现延迟加载异常;另外,延迟加载也可能会导致N+1查询问题。所以,需要谨慎使用这个特性。

这篇关于mybatis多表映射-延迟加载,延迟加载的前提条件是:分步查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/483470

相关文章

MyBatis分页插件PageHelper深度解析与实践指南

《MyBatis分页插件PageHelper深度解析与实践指南》在数据库操作中,分页查询是最常见的需求之一,传统的分页方式通常有两种内存分页和SQL分页,MyBatis作为优秀的ORM框架,本身并未提... 目录1. 为什么需要分页插件?2. PageHelper简介3. PageHelper集成与配置3.

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

在 PyQt 加载 UI 三种常见方法

《在PyQt加载UI三种常见方法》在PyQt中,加载UI文件通常指的是使用QtDesigner设计的.ui文件,并将其转换为Python代码,以便在PyQt应用程序中使用,这篇文章给大家介绍在... 目录方法一:使用 uic 模块动态加载 (不推荐用于大型项目)方法二:将 UI 文件编译为 python 模

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

基于Redis实现附近商铺查询功能

《基于Redis实现附近商铺查询功能》:本文主要介绍基于Redis实现-附近商铺查询功能,这个功能将使用到Redis中的GEO这种数据结构来实现,需要的朋友可以参考下... 目录基于Redis实现-附近查询1.GEO相关命令2.使用GEO来实现以下功能3.使用Java实现简China编程单的附近商铺查询4.Red

mysql递归查询语法WITH RECURSIVE的使用

《mysql递归查询语法WITHRECURSIVE的使用》本文主要介绍了mysql递归查询语法WITHRECURSIVE的使用,WITHRECURSIVE用于执行递归查询,特别适合处理层级结构或递归... 目录基本语法结构:关键部分解析:递归查询的工作流程:示例:员工与经理的层级关系解释:示例:树形结构的数

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

MySQL 复合查询案例详解

《MySQL复合查询案例详解》:本文主要介绍MySQL复合查询案例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录基本查询回顾多表笛卡尔积子查询与where子查询多行子查询多列子查询子查询与from总结合并查询(不太重要)union基本查询回顾查询

Spring框架中@Lazy延迟加载原理和使用详解

《Spring框架中@Lazy延迟加载原理和使用详解》:本文主要介绍Spring框架中@Lazy延迟加载原理和使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、@Lazy延迟加载原理1.延迟加载原理1.1 @Lazy三种配置方法1.2 @Component