MyBatis面试汇总
目录
1.什么是MyBatis?
2.MyBatis的优缺点?
3.MyBatis是如何进行分页?分页插件的原理是什么?
4.MyBatis是如何将sql执行结果封装为目标对象并返回的?有哪几种映射方式?
5.说说MyBatis的缓存机制:
6.如何实现批量插入?
7.MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?
8.#{}和${}的区别是?
1.什么是MyBatis?
- MyBatis是一个半ORM(Object Relation Mapping对象关系映射)框架、是支持自定义SQL、存储过程以及高级映射的持久层框架;
- 内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建传输器、关闭资源等繁杂的过程。程序员直接编写写原生态sql,可以严格控制sql执行性能,灵活度高;
- MyBatis可以使用xml或注解来配置和映射原生信息,将POJO映射成数据库中的记录,避免l几乎所有的JDBC代码和手动设置参数以及获取结果集的工作;
从执行sql到返回result的过程:通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。
2.MyBatis的优缺点?
优点:
- 基于sql语句编程,相当灵活,不会对应程序或者数据库的现有设计造成任何影响,sql写在xml里,解除了SQL与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态sql语句,并可重用;
- 与JDBC相比,消除了JDBC大量冗余的代码,不需要手动开关连接;
- 很好的与各种数据库兼容
- 能够与Spring很好的集成;
- 提供映射标签,支持对象与数据库的ORM字段关系映射,提供对象关系映射标签,支持对象关系组件维护。
缺点:
- SQL语句主要依赖于数据库,导致数据库移植性差,不能随意更换数据库;
- SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的有一定要求。
3.MyBatis是如何进行分页?分页插件的原理是什么?
- MyBatis使用RowBounds对象进行分页(是针对ResultSet结果集执行的内存分页,并非是物理分页)。可以在sql内直接拼写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页,比如:MySQL数据的时候,在原有SQL后面拼写limit。
- 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的SQL,然后重写SQL,根据dialect方言,添加对应的物理分页语句和物理分页参数。
4.MyBatis是如何将sql执行结果封装为目标对象并返回的?有哪几种映射方式?
- 使用标签,一一定义数据库列名和对象属性名之间的映射关系;
- 使用sql列的别名,将列的别名写为对象的属性名;
有了列名与属性名的映射关系后,MyBatis通过反射创建对象,同时使用反射给对象的属性一一赋值并返回,(找不到映射关系的属性,是无法赋值的)
5.说说MyBatis的缓存机制:
MyBatis整体:
一级缓存localCache:
在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的sql,MyBatis提供了一次缓存的方案优化这部分场景,如果是相同的sql语句,会优化命中一级缓存,避免直接对数据库进行查询,提供性能。
每个sqlsession中持有了exectuor,每个Executor中有一个LocalCache。当用户发起查询时,Mybatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。具体实现类的类关系图如图所示:
1.MyBatis一级缓存的生命周期和sqlsession一致;
2.MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺;
3. Mybatis的一级缓存最大范围是sqlsession内部,有多个sqlsession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为statement。
二级缓存:
在上文中提到的一级缓存中,其最大的共享范围就是一个sqlsession内部,如果多个sqlsession之间需要共享缓存,则需要使用到二级缓存。开启二级缓存后,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,先在CachingExecutor进行二级缓存的查询,具体的工作流程如下所示。
二级缓存开启后,同一个namespace下的所有操作语句,都影响着同一个Cache,即二级缓存被多个sqlsession共享,是一个全局的变量。
当开启缓存后,数据的查询执行的流程为:
二级缓存-->一级缓存-->数据库
- MyBatis的二级缓存相对于一级缓存来说,实现了sqlsession之间缓存数据的共享,同时粒度更加细,能够到namespace级别,通过cahce接口实现类不同的组合,对cache的可控性也更强;
- Mybatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻;
- 在分布式环境下,由于默认的MyBatis Cahce 实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将Mybatis 的 Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
6.如何实现批量插入?
首先,创建一个简单的insert语句:<insert id="insertname">insert into names (name) values (#{value}) </insert>
然后在java代码中像下面这样执行批处理插入:list<string> names = new arraylist(); names.add("fred");names.add("barney");names.add("betty");names.add("wilma");// 注意这里 executortype.batchsqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch); try {namemapper mapper = sqlsession.getmapper(namemapper.class);for (string name : names) {mapper.insertname(name);}sqlsession.commit();}catch(Exception e){e.printStackTrace();sqlSession.rollback(); throw e; }finally {sqlsession.close();}
7.MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?
8.#{}和${}的区别是?
取值操作:#{属性值}、${属性值}
- #取值采用占位符的方式,更加安全,能防止sql注入;
- $一般使用场景,以字段为参数时使用;
- 使用#号时候,默认为添加""号;
- 能使用#{},绝不用${}
#{} | ${} | |
1.编译过程 | (占位符)动态解析->预编译处理->执行 | 动态解析->字符串替换(编译)->执行 |
2.是否自动加入单引号 | 对应的变量会自动添加 | 不会 |
3.安全性 | 可以有效的防止SQL注入,提高系统安全性 | 不会 |
4.处理方式 | MyBatis在处理#{}时,会将sql中的#{}替换成?号,调用PreparedStatement的set方法来赋值 | MyBatis在处理${}时,是把${}替换成变量的值 |
(什么是sql注入?sql注入是一种常见的web安全漏洞,主要形成的原因是在数据交互中,前端的数据传入后台处理时,没有做到严格的判断,导致其传入的数据拼接到SQL语句中后,被当作SQL语句中的一部分执行,从而导致数据库受损)
9. MyBatis实现一对一有几种方式?如何操作?
有联合查询和嵌套查询两种
- 联合查询是几个表联合查询,只查询一次,通过resultMap里面配置association节点配置一对一的类就可以完成;
- 嵌套查询是先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表的查询通过select属性配置。
10. MyBatis中比如UserMapper.java是接口,为什么没有实现类还能调用?
使用JDK动态代理+MapperProxy。本质上调用的是MapperProxy的invoke方法
MyBatis面试汇总相关推荐
- Java后端技术面试汇总(第一套)
面试汇总,整理一波,doc文档可点击[ 此处下载] 1.基础篇 1.1.Java基础 • 面向对象的特征:继承.封装和多态 • final, finally, finalize 的区别 • Excep ...
- 用友Java面试汇总
用友Java面试汇总 春招实习 参考意义不大 昨天晚上接到了用友的电话,让我订时间,约好今天1点30 1点40开始电话面试 (1)自我介绍,根据情况进行一些简单提问,例如问了我做项目的感受是什么,进入 ...
- Java开发西安地区最近面试汇总(三)
Java开发西安地区最近面试汇总(三) 1.Spring的循环依赖 构造器的循环依赖 案例 结论 属性的循环依赖 案例 结论 Spring内部是在何时完成的属性注入,又是如何解决的循环依赖. 小结 2 ...
- Java面试汇总>>>初级工程师—面试1000题
面试汇总>>> 每日刷题 001:重载和重写有什么区别?阐述二者是什么? 002:什么是线程池?线程池有什么优点? 003:线程有几种状态,他们是怎么切换的呢? 004:比较一下St ...
- Java校招面试汇总
Java校招面试汇总 一.JavaSE Ⅰ.基础知识 1.Java中引用数据类型有哪些,它们与基本数据类型有什么区别? 2.Java中的自动装箱与拆箱 3.==和equals()的区别 4.stati ...
- MyBatis面试突击
MyBatis是一个优秀的基于Java持久层框架,内部它是封装了JDBC,让开发者不用过多的关心什么创建连接.加载驱动啊等等.如今大企业越来越多用MyBatis,为什么它越来越被广泛应用,以前流行的S ...
- 前端面试汇总(Bootstrap框架)
前端面试汇总(Bootstrap框架) 1 什么是Bootstrap?以及为什么要使⽤Bootstrap? Bootstrap是⼀个⽤于快速开发 Web 应⽤程序和⽹站的前端框架. Bootstrap ...
- 手撸架构,MyBatis 面试42问
技术栈 传送门 JAVA 基础 手撸架构,Java基础面试100问_vincent-CSDN博客 JAVA 集合 手撸架构,JAVA集合面试60问_vincent-CSDN博客 JVM 虚拟机 手撸架 ...
- 秋招提前批面试汇总(嵌入式+c++面经)国电南自 vivo 乐鑫 中兴 大华 联发科 中科创达 腾讯 绿盟 速腾 科大讯飞 深信服 商汤 海康持续更新
秋招 笔试面试题总结链接:https://download.csdn.net/download/saishen/38520965 秋招面试汇总(c++ + 嵌入式面经)持续更新 提前批 国电南自 vi ...
最新文章
- 学习OpenResty编程
- cocos2d-x游戏开发(四)游戏主循环
- excel自动保存_萌新必看!python处理excel实例
- 【Pre蓝桥杯嵌入式】【STM32】学习索引
- C语言学习笔记---文件操作 fopen()函数 和 fclose()函数
- 机器学习基础:朴素贝叶斯(Machine Learning Fundamentals: Naive Bayes)
- Flink Kafka Connector 与 Exactly Once 剖析
- 特斯拉和SolarCity推出太阳能屋顶瓦片
- vector插入和删除操作
- 财经职业技能测试的软件,2020技能 2.财经管理类 职业技能测试考试大纲(试行)...
- 德标螺纹规格对照表_(外)内六角螺塞标准编号-国家标准JB/德标DIN
- python版webpower的edm的api接口
- 共线性分析软件MCScanX安装、报错解决方法及使用
- Containerd shim 进程 PPID 之谜
- 金融套利策略:理解统计套利的工作原理
- 2018再见|2019你好
- Yolo 一文看懂目标检测
- sqlplus: error while loading shared libraries: libclntsh.so.11.1
- 网页中title乱码问题解决方案
- github pages: 如何使用 github 发布网站
热门文章
- 如何激发高中学生学习的动力
- java的 x跟x_关于语法:java中的x ++和++ x有区别吗?
- python以下是变量合法命名的是_Python变量命名规则(超级详细)
- PostgreSQL date_trunc() 截断日期函数,完成定时时间语法.
- EMC | 瞬态传导抗干扰试验与整改
- 物联大世界 2019年国际物联网展会5月在北京盛大召开
- 备战蓝桥杯-枚举、排序、模拟专项练习详解(含有多道蓝桥杯原题)
- docker命令无响应,进入不了容器问题解决
- Failed startup of context o.e.j.w.WebAppContext@e7892a8{/admin,file:///activemq/webapps/admin/,STOPP
- 【Devc++】迷宫小游戏2.0