03---java面试八股文——mybatis-------8题

21、MyBatis实现一对一查询

  1. MyBatis 有两种不同的方式加载关联:

    • 嵌套 Select 查询:通过执行另外一个 SQL 映射语句来加载期望的复杂类型。
    • 嵌套结果映射:使用嵌套的结果映射来处理连接结果的重复子集。
    • 查看mybatis的关联
      MyBatis是一种流行的Java持久化框架,它提供了多种方式来实现一对一关联。以下是几种常见的方式:
  2. 嵌套select查询(Nested Queries):这种方式通过在主查询中使用子查询来获取关联对象的数据。在MyBatis中,可以使用<select>标签嵌套另一个<select>标签来实现一对一关联查询。具体操作是在主查询中使用子查询获取关联对象的数据,并将其映射到主对象的属性中。

<resultMap id="blogResult" type="Blog"><association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
</resultMap><select id="selectBlog" resultMap="blogResult">SELECT * FROM BLOG WHERE ID = #{id}
</select><select id="selectAuthor" resultType="Author">SELECT * FROM AUTHOR WHERE ID = #{id}
</select>
  1. 嵌套结果映射(Nested Result Maps):这种方式通过在结果映射中定义嵌套的结果映射来实现一对一关联。在MyBatis中,可以使用<resultMap>标签定义嵌套的结果映射,然后在主结果映射中引用它。具体操作是在主结果映射中使用<association>标签引用关联对象的结果映射。

    • 延迟加载(Lazy Loading):这种方式通过延迟加载关联对象的数据来实现一对一关联。在MyBatis中,可以使用<association>标签的fetchType属性设置为lazy来启用延迟加载。具体操作是在需要访问关联对象数据时才进行加载。
  2. 嵌套查询和嵌套结果映射的组合:有时候,可以将嵌套查询和嵌套结果映射结合起来使用,以实现更复杂的一对一关联查询。

在这里插入图片描述

22、MyBatis实现一对多查询有几种方式,怎么操作的?((关联(association))

MyBatis是一种Java持久层框架,它提供了多种方式来实现一对多的关系。以下是几种常见的方式及其操作方法:

  1. 嵌套select查询(Nested Queries):通过在主查询中嵌套子查询来获取关联对象的数据。在MyBatis的Mapper XML文件中,可以使用<collection>标签定义一个嵌套查询,通过指定子查询的SQL语句和结果映射关系来实现一对多的关系。

    示例代码:

<select id="selectPostsForBlog" resultType="Post">SELECT * FROM POST WHERE BLOG_ID = #{id}
</select><resultMap id="blogResult" type="Blog"><collection property="posts" javaType="ArrayList" column="id" ofType="Post" select="selectPostsForBlog"/>
</resultMap><select id="selectBlog" resultMap="blogResult">SELECT * FROM BLOG WHERE ID = #{id}
</select>

1.1 . 延迟加载(Lazy Loading):在查询主对象时,不立即加载关联对象的数据,而是在需要使用关联对象时再进行加载。在MyBatis的Mapper XML文件中,可以使用<collection>标签的fetchType属性设置为lazy来实现延迟加载。

示例代码:

 <select id="selectPostsForBlog" resultType="Post">SELECT * FROM POST WHERE BLOG_ID = #{id}
</select><resultMap id="blogResult" type="Blog"><!-- collection标签的含义: posts 是一个存储 Post 的 ArrayList 集合--><collection property="posts" javaType="ArrayList" column="id" fetchType="lazy" ofType="Post" select="selectPostsForBlog"/>
</resultMap><select id="selectBlog" resultMap="blogResult">SELECT * FROM BLOG WHERE ID = #{id}
</select>
  1. 嵌套结果映射(Nested Result Maps):通过在结果映射中定义嵌套的结果映射来实现一对多的关系。在MyBatis的Mapper XML文件中,可以使用<resultMap>标签中使用<collection>标签定义一个嵌套的结果映射。

    示例代码:

<select id="selectBlog" resultMap="blogResult">selectB.id as blog_id,B.title as blog_title,B.author_id as blog_author_id,P.id as post_id,P.subject as post_subject,P.body as post_body,from Blog Bleft outer join Post P on B.id = P.blog_idwhere B.id = #{id}
</select><resultMap id="blogResult" type="Blog"><id property="id" column="blog_id" /><result property="title" column="blog_title"/><collection property="posts" ofType="Post"><id property="id" column="post_id"/><result property="subject" column="post_subject"/><result property="body" column="post_body"/></collection>
</resultMap>

这段代码和上面一段一样的作用

<select id="selectBlog" resultMap="blogResult">selectB.id as blog_id,B.title as blog_title,B.author_id as blog_author_id,P.id as post_id,P.subject as post_subject,P.body as post_body,from Blog Bleft outer join Post P on B.id = P.blog_idwhere B.id = #{id}
</select><resultMap id="blogResult" type="Blog"><id property="id" column="blog_id" /><result property="title" column="blog_title"/><collection property="posts" ofType="Post" resultMap="blogPostResult" columnPrefix="post_"/>
</resultMap><resultMap id="blogPostResult" type="Post"><id property="id" column="id"/><result property="subject" column="subject"/><result property="body" column="body"/>
</resultMap>

示例:一个用户上面有多个账户

public class User implements Serializable {private Integer id;private String username;private String address;private String sex;private Date birthday;//一对多关系映射:主表实体应该包含从表实体的集合引用private List<Account> accounts;
}public class Account implements Serializable{private Integer aid;private Integer uid;private Double money;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.itheima.dao.IUserDao"><!--定义 user 的 resultMap --><resultMap id="userAccountMap" type="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><!--配置user对象account集合的映射ofType集合中元素的类型--><collection property="accounts" ofType="account" fetchType="lazy"><id column="aid" property="id" ></id><result column="uid" property="uid"></result><result column="money" property="money"></result></collection></resultMap><!--配置查询所有--><select id="findAll" resultMap="userAccountMap">select u.*, a.id as aid, a.uid, a.money from user u left outer join account a on u.id = a.uid</select></mapper>

23、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

  1. Mybatis 仅支持association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
    • 它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器 invoke()方法发现 a.getB()是null 值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是 a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

补充什么是 CGLIB?

  1. 什么是 CGLIB?
    • CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。
    • 通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB 是一个好的选择。
  2. CGLIB 的原理
    • 动态生成一个要代理类的子类,子类重写要代理的类的所有不是 final 的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。
  3. CGLIB 底层:采用ASM字节码生成框架,使用字节码技术生成代理类,比使用 Java 反射效率要高。

24、Mybatis的一级、二级缓存:

  1. 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
  2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/>
  3. 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

25、什么是MyBatis的接口绑定?有哪些实现方式?

  1. 接口绑定,就是在MyBatis 中任意定义接口,然后把接口里面的方法和 SQL语句绑定, 我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置。
  2. 接口绑定有两种实现方式:
    • 一种是通过注解绑定,就是在接口的方法上面加上@Select、@Update 等注解,里面包含 Sql 语句来绑定;
    • 另外一种就是通过 xml里面写SQL来绑定, 在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。当Sql语句比较简单时候,用注解绑定, 当SQL语句比较复杂时候,用 xml 绑定,一般用 xml 绑定的比较多。

26、Mapper编写有哪几种方式

  1. 第一种:接口实现类继承SqlSessionDaoSupport:使用此种方法需要编写mapper 接口,mapper 接口实现类、mapper.xml 文件。

1、在 MybatisConfig.xml 中配置 mapper.xml 的位置

<mappers><mapper resource="mapper.xml 文件的地址" /><mapper resource="mapper.xml 文件的地址" /></mappers>

2、定义 mapper 接口
3、实现类继承SqlSessionDaoSupport ,mapper 方法中可以 this.getSqlSession()进行数据增删改查。
4、spring 配置

<bean id=" " class="mapper接口的实现类"><property name="sqlSessionFactory" ref="sqlSessionFactory"></property></bean>
  1. 第二种:使用org.mybatis.spring.mapper.MapperFactoryBean:

1、在 MybatisConfig.xml 中配置 mapper.xml 的位置,如果 mapper.xml 和mappre 接口的名称相同且在同一个目录,这里可以不用配置

<mappers><mapper resource="mapper.xml 文件的地址" /><mapper resource="mapper.xml 文件的地址" /></mappers>

2、定义 mapper 接口:
2.1、mapper.xml 中的 namespace 为 mapper 接口的地址
2.2、mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一

3、Spring 中定义

<bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean"><property name="mapperInterface" value="mapper接口地址" /><property name="sqlSessionFactory" ref="sqlSessionFactory" /></bean>
  1. 第三种:使用mapper 扫描器:

1、mapper.xml 文件编写:
mapper.xml 中的 namespace 为 mapper 接口的地址;
mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致;
如果将mapper.xml和mapper接口的名称保持一致则不用在Mybatis.xml中进行配置。

2、定义 mapper 接口:
注意mapper.xml 的文件名和 mapper 的接口名称保持一致,且放在同一个目录

3、配置 mapper 扫描器:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="mapper 接口包地址"></property><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/></bean>

4、使用扫描器后从spring 容器中获取 mapper的实现对象

27、使用MyBatis的mapper接口调用时有哪些要求?

  1. Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同;
  2. Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同;
  3. Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql的resultType 的类型相同;
  4. Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径

28、简述Mybatis的插件运行原理,以及如何编写一个插件。

  1. Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
  2. 编写插件:实现Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/571857.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java程序设计】【C00344】基于Springboot的船舶维保管理系统(有论文)

基于Springboot的船舶维保管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及i…

腾讯VS网易:一场不见终局的游戏未来之战

国内游戏霸主腾讯最近赚足了眼球。 总体上看&#xff0c;腾讯手握“游戏社交”两大王牌&#xff0c;最近发布的财报十分亮眼&#xff0c;其2023年总营收和净利润分别同比增长10%和36%&#xff0c;展现了互联网巨头的强劲活力。 然而巨头亦有焦虑&#xff0c;增值服务营收同比…

ChatGPT5.0最新爆料

前言 Chat GPT 5 发布日期预测开始飞速发展&#xff0c;期待这将是 OpenAI 迄今为止最先进的大型语言模型。OpenAI 是否正在开发 GPT 5&#xff1f;如果是这样&#xff0c;GPT 5 什么时候出来&#xff1f;OpenAI 首席执行官山姆奥特曼 &#xff08;Sam Altman&#xff09; 将再…

【Java多线程】1——多线程知识回顾

1 多线程知识回顾 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star…

线程安全集合类原理

一、ConcurrentHashMap (一)、HashMap 1、JDK7 并发死链 采用头插法 扩容源码(扩容时并没有创建新的节点&#xff0c;只是将引用挂在不同的地方) void transfer(Entry[] newTable, boolean rehash) {int newCapacity newTable.length;for (Entry<K,V> e : table) {…

Ubuntu20.04 安装 OpenCV3 过程中遇到的各种问题及其解决办法

文章目录 前言开始安装OpenCV3问题1&#xff1a;ICV: Failed to download ICV package: ippicv_linux_20151201.tgz.1.1 具体步骤 问题2&#xff1a;/usr/include/c/7/cstdlib:75:15: fatal error: stdlib.h: No such file or directory问题3&#xff1a;error: CODEC_FLAG_GLO…

Linux指令大全,第二篇(超详细版)

目录 9.1 链接文件的命令 10.1. 用户和权限 11.1 文件压缩和解压命令 12.1 文件操作命令补充 13.1 Vim编辑器的使用 14.1 Linux开关机命令 15.1 Shell Linux 程序设计&#xff08;未完持续更新~&#xff09; 16.1 以上运行效果图如下 9.1 链接文件的命令 9.1.1 …

codesys通过moudbus TCP连接西门子1214c,西门子做客户端

思路在codesys中发送数据到西门子&#xff0c;西门子原封不动的将数据传回。 1.首先配置codesys; 我设置了500个&#xff0c;但是好像发不这么多&#xff0c;只能120多个。因为什么来我忘了。但是这里不影响。 2.配置映射&#xff1a; 3.写代码 PROGRAM PLC_PRG VARarySendDa…

方案分享 | 嵌入式指纹方案

随着智能设备的持续发展&#xff0c;指纹识别技术成为了现在智能终端市场和移动支付市场中占有率最高的生物识别技术。凭借高识别率、短耗时等优势&#xff0c;被广泛地运用在智能门锁、智能手机、智能家居等设备上。 上海航芯在2015年进入指纹识别应用领域&#xff0c;自研高性…

python第三次作业

1、求一个十进制的数值的二进制的0、1的个数 def count_0_1_in_binary(decimal_num):binary_str bin(decimal_num)[2:]count_0 binary_str.count(0)count_1 binary_str.count(1)return count_0, count_1decimal_number int(input("十进制数&#xff1a;")) zero…

DVB-S系统仿真学习

DVB-S系统用于卫星电视信号传输&#xff0c;发送端框图如下所示 扰码 实际数字通信中&#xff0c;载荷数据的码元会出现长连0或长连1的情况&#xff0c;不利于接收端提取时钟信号&#xff0c;同时会使得数据流中含有大量的低频分量&#xff0c;使得QPSK调制器的相位长时间不变…

VGG16神经网络搭建

一、定义提取特征网络结构 将要实现的神经网络参数存放在列表中&#xff0c;方便使用。 数字代表卷积核的个数&#xff0c;字符代表池化层的结构 cfgs {"vgg11": [64, M, 128, M, 256, 256, M, 512, 512, M, 512, 512, M],VGG13: [64, 64, M, 128, 128, M, 256, …