当前位置: 首页 > news >正文

mybatis面试题及回答

1、什么是mybatis?ORM是什么?JPA是什么?
2、讲下mybatis的缓存?
1一级二级都是基于PerpetualCache的HashMap本地缓存;
2一级缓存是SQLSession级别的,默认是开启的,当Session Flush或close之后,缓存就会清空;
3二级缓存的作用域是mapper的同一个namespace,默认是关闭的,并且可以自定义存储源,如EHcache,开启二级缓存需要实体类实现序列化接口,然后在Mapper中配置cache标签;
4当某一个作用域进行了增删改操作后,默认将该作用域下所有缓存清空;
3、mybatis的优点和缺点?
优点:
1mybatis完全把sql语句从程序代码中抽离出来,放在单独的xml文件中,为程序的维护带来了便利;
2mybatis底层封装了jdbc的调用细节,能将查询的结果集自动封装成java bean对象,消除了大量的冗余代码
3程序员自己编写sql,可以结合数据库的自身特性,灵活控制;
4能够很好的与spring集成
缺点:
1当字段名多、关联表多的时候,sql语句的编写工作量很大;
2sql依赖于数据库,导致数据库的移植性差;
4、mybatis是如何进行分页的?分页插件的原理是什么?
a、使用rowbounds对象进行分页,他是针对ResultSet结果集执行的内存分页;
b、使用sql语句分页;
c、使用分页插件进行分页;
原理:实现了mybatis提供的接口,实现了自定义插件,在插件的拦截方法中拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和参数;
5、简述mybatis的插件运行原理,以及如何编写一个插件?
原理:mybatis只能编写针对于ParameterHandler、ResultSetHandler、StatementHandler、executor这四个接口的插件,mybatis是通过动态代理来实现接口方法的拦截功能,每当执行这四种接口对象的方法时,就会进入拦截方法,是属于AOP的思想。
自定义插件:实现Interceptor接口并实现intercept()方法,然后给插件编写注解,指定需要拦截哪个接口的哪些方法,然后在核心配置文件中添加自定义的插件;
6、mybatis动态sql是做什么的?有哪些标签?原理是?
动态SQL:可以让我们在xml映射文件中,以标签的形式完成逻辑判断、动态拼接sql的功能
9个标签:trim where if set foreach choose when otherwise bind
原理:使用OGNL从sql参数对象中计算表达式的值,然后根据这个值去动态拼接sql;
7、#{}和${}的区别是什么?
1前者为预编译处理,后者为字符串替换;
2前者会将sql语句中的#{}替换为问号,然后使用PreparedStatement的set方法来赋值;
3后者会直接将sql中的${}替换为变量的值;
4前者使用的最多,因为能有效防止sql注入;
8、为什么说mybatis是半自动ORM映射工具?
因为mybatis在查询关联对象或者关联集合对象的时候,需要手动的编写sql来完成;而hibernate可以根据ORM直接获取;
9、mybatis是否支持延迟加载?实现原理是什么?
1只支持association关联对象和collection关联集合的对象的延迟加载,需要在配置文件中setting标签中lazyLoadingEnable设为true,还有aggressiveLazyLoading它默认为false,即可开启懒加载,为true时所有属性都会立即加载;
2原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法;
10、mybatis和hibernate有什么不同?
1mybatis不完全是一个ORM框架;
2mybatis直接手动编写原生态sql,所以可以严格控制sql的执行性能,灵活度高,但是无法做到数据库无关性,然后编写复杂sql的工作量大;
3hibernate ORM能力强,数据库无关性好,对于对象关系模型强的程序使用hibernate可以节省很多的代码,提高开发效率;
11、简述mybatis的映射文件和内部数据结构的映射关系?
mybatis将所有xml配置信息都封装到configuration对象内部,在mapper映射文件中,parameterMap标签会被解析为parameterMap对象,其子元素会被解析为parameterMapping对象;resultMap标签会被解析为resultMap对象,其子元素会被解析为resultMapping对象;增删改查标签会被解析为mappedStatement对象;SQL语句会被解析为boundSql对象;
12、什么是mybatis的接口绑定?有什么好处?
1就是将接口方法与sql语句绑定,直接调用接口方法就可以使用;
2好处是,比起SQLSession提供的方法,有了更加灵活的配置;
13、接口绑定有几种实现方式?分别是怎么实现的?
1使用注解绑定,在里面写增删改查语句来绑定;
2通过在映射文件中编写sql来绑定,需要指定映射文件中的namespace为接口的全路径名;
3一般xml用的多;
14、什么情况使用注解绑定?什么情况用xml绑定?
当SQL语句比较简单的时候使用注解,复杂的时候使用xml;
15、mybatis实现一对一有几种方式?具体怎么操作?
a、联合查询:几个表联合查询,只执行一条sql语句,用association标签来配置映射关系;
b、嵌套查询:先查一个表,根据这个表的结果的外键id再去另一个表查询数据,也是通过association配置;
16、mybatis里的动态sql是怎么设定的?用什么语法?
主要是通过if标签来实现的,使用OGNL语法,但是想要写完整,必须配合where、trim标签;where标签是判断子标签有内容就插入where;trim标签是用于自定义前缀后缀等规则的标签;
17、mybatis是如何将sql执行结果封装为目标对象并返回的?有哪些映射方式?
a、使用resultMap标签,去定义列名与实体类属性名之间的关系;
b、给sql列名设置别名,与实体类属性名一一对应;
c、在核心配置文件中setting标签中配置mapUnderscoreToCamelCase为true,即可将下划线名转换为驼峰命名;
有了列名与属性名直接的映射之后,mybatis通过反射创建对象,同时通过反射给对象属性逐一赋值并返回;
18、xml映射文件中,有哪些标签?
parameterMap、resultMap、sql、include、selectKey,加上动态sql9个标签,期中sql为sql片段标签,可以通过include标签引入sql片段,selectKey则为不支持自增的主键生成策略;
19、通常一个xml映射文件都会对应一个dao接口,dao的工作原理是什么?是否可以重载dao的方法?
原理:运行时会为dao创建proxy代理对象,然后代理对象拦截接口方法,去执行对应的sql;
不能重载,因为是通过全路径名+方法名的策略去寻找的,如果重载了方法,会出现重复的方法名;
20、mybatis映射文件中,a标签通过include引用了b标签的内容,b标签可以定义在任何地方吗?
可以在任何地方,因为mybatis解析映射文件是按顺序的,当解析到a标签时,发现引用了b标签,但是还没解析b标签,此时就会把a标签设置为待解析的状态,当解析完全部标签,又会重新解析待解析的标签,此时就正常解析完成了;
21、mybatis映射文件中,不同的映射文件,标签id是否可以重复?
不同的xml映射文件,如果配置了namespace,那么内部的sql id可以重复;如果没有配置namespace,那么id不能重复;
22、mybatis怎么执行批处理?
使用BatchExecutor执行;
23、mybatis有哪些executor执行器?他们的区别是什么?
simpleExecutor:每执行一次select或update,就会开启一个statement对象,用完立刻关闭;
reuseExecutor:执行select或update,以sql作为key去查找statement对象,存在就直接使用,不存在就创建,用完之后不关闭,而是存入map;
batchExecutor:执行update时,将所有sql都添加到批处理中,等待统一执行;
24、mybatis如何指定使用哪一种executor执行器?
在核心配置文件中可以指定默认的ExecutorType执行器类型;
也可以手动给DefaultSqlSessionFactory的创建SqlSession方法传递ExecutorType类型的参数;
25、mybatis是否可以映射enum枚举类?
可以映射任何对象到表的一列上,自定义一个TypeHandler接口,实现TypeHandler的setParameter()和getResult()方法,用于完成javaType与jdbcType的相互转换,分别代表设置sql问号占位符与获取列的查询结果;
26、如何获取自动生成的键值?
将useGeneratorKeys属性设置为true;
27、在mapper中如何传递多个参数?
1直接在映射文件中使用#{}索引获取;
2在接口方法的参数列表中使用@Param注解,就可以在映射文件中用#{}获取;
3将多个参数封装为map;
4javaBean传参;
在使用mapper接口传递参数时,其底层是采用了动态代理的方式,表面上是调用mapper接口,而实际上是通过动态代理去调用SqlSession对应的方法,参考DefaultSqlSession的getMapper()方法实现,最终会获得一个代理了mapper接口的mapperProxy对象。mapperProxy对象在调用mapper接口方法时会把传递的参数做一个转换,然后把转换后的参数作为入参,去调用SqlSession对应的方法。
28、resultType和resultMap的区别?
1当查询的列名对应上了实体类的所有属性名时就使用resultType;
2如果名字不一致,则需要手动编写resultMap将查询结果映射到属性上;
29、使用mybatis的mapper接口调用时有什么要求?
1映射文件的namespace为接口的类路径;
2接口方法名与映射文件中定义的每一个sql的id一致;
3接口方法的入参类型与映射文件的每一个sql的parameterType类型相同;
4接口方法的返回值类型与映射文件的每一个sql的resultType类型相同;
30、mybatis相对于ibatis来说比较大的改进有哪些?
1有了接口绑定,包括注解绑定和xml绑定;
2动态sql由原先的节点配置改进为OGNL表达式;
3引进了association与collection标签用于配置映射关系;
31、mybatis与ibatis的核心处理类分别叫什么?
mybatis为SqlSession,ibatis为SQLMapClient;
32、mybatis与ibatis的细节上有什么区别?
1原先的##表达式改进为#{},$$表达式改进为${};
2原先的sql标签里的class改名为type;
3原先的queryForObject、queryForList改名为selectOne、selectList;
4原先的别名在映射文件中设置,现在在核心文件中设置;
33、mybatis执行一对一、一对多有哪些实现方式?
1单独发送一个sql去查询关联对象,赋给主对象,然后返回主对象;
2使用嵌套查询,内外连接,一部分列是A对象的属性值,另一部分是关联对象B的属性值,好处是只发一个sql查询;
34、mybatis连接数据库过程中数据库链接中断如何处理?
为DataSource的max_idle_time最大空闲时间属性,设置一个值,超过这个时间socket就会关闭,这样就不会浪费资源,因为服务器维持一个socket是很消耗资源的。
为connect_timeout链接超时时间设置一个值,超过这个时间就会不继续等待。
35、在开发过程中,经常遇到插入重复的现象,这种情况如何解决?
假设同时有三个线程:线程a、线程b、线程c,同时进行插入操作。
1判断数据库是否有数据,有的话则无所作为。没有数据的话,则进行下面第2步。
2大家都要去竞争锁,用redis当锁,即:redis set key,其中只有一个操作a会成功,其他并发的线程b和c会失败。
3上面set key 成功的线程a,开始执行插入数据操作,无论是否插入数据成功,都在最后del key。
4如果拿到锁的线程a没有插入成功,即便是尝试了数次也没有插入成功,此时定是系统出现了bug,应该及时寻找。
36、事务执行过程中宕机的应对处理办法?
1不会自动继续执行也不会自动直接回滚。但可以依据事务日志手动选择继续执行还是回滚;
2事务开启时,事务中的操作,都会先写入存储引擎的日志缓冲中,在事务提交之前,这些缓冲的日志都需要提前刷新到磁盘上持久化,这就是人们口中常说的“日志先行”(Write-Ahead Logging),日志分为两种类型:redo log和undo log;
3redo log用于记录所有的语句;undo log主要记录了数据在每个操作之前的状态,用于进行回滚的操作;
4如果事务没有提交,那就不会造成任何影响;
5如果是在提交的时候宕机,恢复之后可以选择回滚事务,也可以选择继续提交事务;
6如果是在提交之后写入数据库时宕机,可以根据redo log把数据刷回磁盘中;
7所以redo log其实保障的是事务的持久性和一致性,而undo log则保障了事务的原子性;
37、Java客户端中的一个connection是不是在MySQL中就对应一个线程来处理?
1在高性能服务器端开发,底层往往是靠IO复用来处理的,这种模式就是单线程+事件处理机制。
2在MySQL中有一个主线程,这是单线程,它不断的循环查看socket是否有读写事件,如果有,就从线程池中找一个工作线程来处理这个socket的读写事件,完成之后这个工作线程会回到线程池。
3所以,Java客户端中的一个connection是由一个监听socket的主线程+线程池里面固定数目的工作线程来处理。



如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,

咱们下期见!答案获取方式:已赞 已评 已关~

学习更多知识与技巧,关注与私信博主(03)

相关文章:

  • 奔腾电力面试题
  • 【leetcode】905. 按奇偶排序数组 (简单)
  • Java--MybatisPlus入门;与Mybatis区别;简单使用(一)
  • #ubuntu# #git# repository git config --global --add safe.directory
  • 【数据结构】——二叉树oj题详解
  • 性能测试:工具篇:Jmeter实时可视化平台搭建
  • 你该用什么的美剧学英语?
  • 面试算法 二叉树的遍历,方法 :迭代 ,前序遍历: 中序遍历: 后序遍历: 层序遍历
  • Matlab常用函数(control)
  • 推荐10款好用的数据可视化工具,赶紧收藏
  • Java刷题面试系列习题(六)
  • 解决:vue-cli-service不是内部或外部命令
  • 手把手教你深度学习和实战-----全连接神经网络
  • VSCode 配置 C++ 环境
  • 2021年研究生数模B题论文记录
  • JavaScript-如何实现克隆(clone)函数
  • Angular6错误 Service: No provider for Renderer2
  • C学习-枚举(九)
  • Docker下部署自己的LNMP工作环境
  • Hibernate最全面试题
  • JavaScript HTML DOM
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Python实现BT种子转化为磁力链接【实战】
  • React-flux杂记
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 基于 Babel 的 npm 包最小化设置
  • 浏览器缓存机制分析
  • 那些被忽略的 JavaScript 数组方法细节
  • 排序算法学习笔记
  • 小试R空间处理新库sf
  • 白色的风信子
  • ​2021半年盘点,不想你错过的重磅新书
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • (+4)2.2UML建模图
  • (27)4.8 习题课
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (Git) gitignore基础使用
  • (Matlab)使用竞争神经网络实现数据聚类
  • (二)pulsar安装在独立的docker中,python测试
  • (力扣)循环队列的实现与详解(C语言)
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .netcore 获取appsettings
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • [ C++ ] STL_stack(栈)queue(队列)使用及其重要接口模拟实现
  • [ASP]青辰网络考试管理系统NES X3.5
  • [bzoj 3124][sdoi 2013 省选] 直径
  • [CF543A]/[CF544C]Writing Code
  • [CLickhouse] 学习小计
  • [CodeForces-759D]Bacterial Melee
  • [dts]Device Tree机制