-
Mybatis面试题
0.什么是Mybatis,优点,适用场合
是一个半自动化的持久层框架,内部封装了的jdbc,开发时候只需要关注sql,不用去浪费时间处理驱动连接等复杂的过程
优点:灵活,sql和java代码分开,便于管理,一个专注业务、一个专注数据,提供映射标签,支持编写动态sql,简单易学
对性能要求高,需求变化多的项目可以选择
1.Mybatis 中 #{}和 ${}的区别是什么?
#{}是预编译处理,${}是字符串替换。在处理#时候会将#{}替换为?将$替换为变量的值
#{}可以防止sql注入 提高安全性
既然${}会引起sql注入,为什么有了#{}还需要有${}呢?那其存在的意义是什么?
原生jdbc不支持占位符的地方可以使用${}进行取值
比如分表:按照年份分表
Select * from ${year}_salary
Select * from xx order by ${name} ${order}
#{}主要用于预编译,而预编译的场景其实非常受限,而${}用于替换,很多场景会出现替换,而这种场景可不是预编译
3. 说一下 Mybatis 的一级缓存和二级缓存?
一级缓存(本地缓存):SQLSession级别的缓存,作用域是SQlSession,默认开启一级缓存。
与数据库同一次会话期间查到的数据放到本地缓存中,以后需要获取相同的数据直接从缓存中取不用在继续查询
一级缓存失效情况:
1.sqlSession不同
2.sqlsession相同,查询条件不同
3. sqlsession相同,二次查询之间执行了增删改操作
4. sqlsession相同,手动清除了一级缓存
二级缓存(全局缓存):基于namespace级别的缓存,一个namespace对应一个二级缓存
第一次mapper调用查询会放到对应的mapper二级缓存中,第二次调用相同的namespace下mapper映射文件会去对应的二级缓存中取结果
进行增删改会清空
4. Mybatis 有哪些执行器(Executor)?
SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。
Mybatis中如何指定使用哪一种Executor执行器?
在Mybatis配置文件中,可以指定默认的ExecutorType执行器类型,也可以手动给DefaultSqlSessionFactory的创建SqlSession的方法传递ExecutorType类型参数。
5. Mybatis是如何进行分页的?Mybatis 分页插件的实现原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
6. Mybatis 有几种分页方式?
Sql分页使用limit,拦截器分页,使用RowBounds对象进行分页,插件分页
7. RowBounds 是一次性查询全部结果吗?为什么?
不是,mybatis是对jdbc的封装,在jdbc驱动中有Fetch Size的配置,它规定每次最多从数据库查询多少条数据。
8. Mybatis 逻辑分页和物理分页的区别是什么?
物理分页是数据库本身提供的分页方式,效率高弥补了逻辑分页的缺点,不同数据库不同写法
逻辑分页是查询所有数据利用代码获取需要的数据,所有数据库统一写法,效率低消耗大量内存,有内存溢出的危险,对数据库压力大
9. Mybatis 如何编写一个自定义插件?
10. 通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,
然后将sql执行结果返回。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。
11. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种:使用resultMap标签,逐一定义列名和对象属性名之间的映射关系
第二种:使用sql设置别名功能,将别名定义为属性名
列名和属性名有映射关系后,mybatis通过反射创建对象,将值反射给对象的属性并返回
12. Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
trim where set foreach if choose when bind
使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,完成动态sql功能
13. Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?
不同的Xml映射文件,如果配置了namespace,那么id可以重复
如果没有配置namespace,那么id不能重复
14. 为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,
所以,称之为半自动ORM映射工具。
15. 一对一、一对多的关联查询 ?
<!--association 一对一关联查询 多对一 -->
<!--collection 一对多关联查询 -->
16. Mybatis是什么?与IBatis有什么区别?
1)ibatis本是apache的一个开源项目,2010年这个项目由apache software foundation 迁移到了google code,并且改名为mybatis。
2)Mybatis实现了接口绑定,使用更加方便,而iBatis不支持。
注:Mybatis支持在接口上使用注解的方式,但是不建议使用,当遇到复杂SQL时该方式有局限性
3)对象关系映射的改进,效率更高,iBatis实现关系映射使用"子查询",而Mybatis不但支持子查询还增加了分步查询。
4)MyBatis采用功能强大的基于OGNL的表达式来消除其他元素。
5)SQL映射的语法区别,例如:动态SQL、传入参数、接收参数、存储过程等
17. Mybatis中在哪使用了命名空间?
在mapper映射文件中的mapper标签中的namespace属性上使用
18. mybatis 动态sql标签中循环标签中有哪些属性,各自的作用。
1)if 标签
if标签通常用于WHERE语句、UPDATE语句、INSERT语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。
2) foreach 标签
foreach标签主要用于在sql中对集合进行迭代。也常用到批量删除、添加等操作中。
3) choose标签
MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。
当choose中所有when的条件都不满则时,则执行 otherwise中的sql。
类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。
4)where标签
如果where标签包含的标签中有返回值的话,它就插入一个"where"。
此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。
5)set 标签
使用set标签可以将动态的配置set关键字,和剔除追加到条件末尾的任何不相关的逗号。
6)trim标签
格式化输出,也可以通过trim标签设定或忽略前后缀来实现格式化输出
7)sql标签
当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为SQL片段,方便调用。
8)include标签
用于引用定义的SQL片段
19. mybatis 动态sql中使用<where>标签与直接写where关键字有什么区别?
where标签为MyBatis的动态语句。where关键字是SQL语句中的where子句。
在mybatis动态SQL中,若直接用where子句的话可能会导致sql语法错误,查询失败。
20.如何获取自动生成的(主)键值?
将usegeneratedkeys设置为true,设置获取主键策略 keyproperty指定返回的主键值的属性
21.数据库连接中断怎么处理?
connection操作底层是一个循环处理操作,因此可以进行时间有关的参数:
max_idle_time : 表明最大的空闲时间,超过这个时间socket就会关闭
connect_timeout : 表明链接的超时时间
22.在开发过程中,经常遇到插入重复的现象,这种情况应该怎么解决
插入的过程一般都是分两步的:先判断是否存在记录,没有存在则插入否则不插入。如果存在并发操作,那么同时进行了第一步,然后大家都发现没有记录,最后在第二步的时候都插入了数据从而造成数据的重复。解决插入重复的思路可以是这样的:
下面场景,假设同时有三个线程:线程a、线程b、线程c,进行插入操作。
(1)判断数据库是否有数据,有的话则无所作为。没有数据的话,则进行下面第2步。
(2)大家都要去竞争锁,用redis当锁,即:redis set key,其中只有一个操作a会成功,其他并发的线程b和c会失败的。
(3)上面set key 成功的线程a,开始执行插入数据操作,无论是否插入数据成功,都在最后del key。【注】插入不成功可以多尝试几次,增加成功的概率。
(4)如果拿到锁的线程a没有插入成功,即便是尝试了数次也没有插入成功,此时定是系统出现了bug,应该搞一个短信报警机制,让研发人员及时发现问题。
23.事务执行过程中宕机的应对处理方式?
24.Java客户端中的一个connection问题?
25.在mapper中如何传递多个参数?
在对应的xml中使用#{param1} #{param2}到n排序
或者在dao层使用@param注解
有对应属性的实体类用实体类
或者用Map定义
26. Mybatis运行原理?
1)加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着<select | update | delete | insert>标签项。
2)SqlSessionFactoryBuilder通过Configuration对象生成SqlSessionFactory,用来开启SqlSession。
3)SqlSession对象完成和数据库的交互:
4)用户程序调用mybatis接口层api(即Mapper接口中的方法)
5)SqlSession通过调用api的Statement ID找到对应的MappedStatement对象
6)通过Executor(负责动态SQL的生成和查询缓存的维护)将MappedStatement对象进行解析,sql参数转化、动态sql拼接,生成jdbc Statement对象
7)JDBC执行sql。
8)借助MappedStatement中的结果映射关系,将返回结果转化成HashMap、JavaBean等存储结构并返回。
-
相关阅读:
C# 获取当前时间戳和将时间戳转为时间Datetime类型的方法
Dynamics CRM 365 窗体的Lookup字段通过JS按照某个字段过滤数据
Dynamic CRM 365 启用用户systemuser、修改用户systemuser的时候报错:The selected object could not be found. Verify that the object exists in both the database and Active Directory.
Dynamics 365 V9.0版本后引入多选项集,SQL查询条件如何写
Dynamics 365 V9.0版本后引入多选项集,SQL查询时,如何显示选中的选项名称
SQLite实现Top功能
RecyclerView滑动到指定位置
使用Intent传递对象(两种)
Android获取当前系统日期和时间
jxl自动设置列宽
-
原文地址:https://www.cnblogs.com/kmcl1314/p/14416094.html
Copyright © 2020-2023
润新知