Java面试题---Mybatis

Mybatis

1.mybatis 中 #{}和 KaTeX parse error: Expected 'EOF', got '#' at position 12: {}的区别是什么? #̲{}是预编译处理,{}是字符串替换。
(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
(2)mybatis在处理 时 , 就 是 把 {}时,就是把 {}替换成变量的值。
(3)使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。

2.mybatis 有几种分页方式?
数组分页 查询出全部数据,然后再list中截取需要的部分。
sql分页
拦截器分页
RowBounds分页

3.RowBounds 是一次性查询全部结果吗?为什么?
RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据。因为 MyBatis 是对 JDBC 的封装,在 JDBC 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在执行 next() 的时候,去查询更多的数据。 就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,要取 4 次才能把钱取完。对于 JDBC 来说也是一样,这样做的好处是可以有效的防止内存溢出。

4.mybatis 逻辑分页和物理分页的区别是什么?
逻辑分页,使用 MyBatis 自带的 RowBounds 进行分页,它是一次性查询很多数据,然后在数据中再进行检索;
物理分页,自己手写 SQL 分页或使用分页插件 PageHelper,去数据库查询指定条数的分页数据形式。

5.mybatis 是否支持延迟加载?延迟加载的原理是什么?
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()方法的调用。这就是延迟加载的基本原理。当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。

6.说一下 mybatis 的一级缓存和二级缓存?
一级缓存是 SqlSession 级别的,是 MyBatis 自带的缓存功能,并且无法关闭,因此当有两个 SqlSession 访问相同的 SQL 时,一级缓存也不会生效,需要查询两次数据库;
二级缓存是 Mapper 级别的,只要是同一个 Mapper,无论使用多少个 SqlSession 来操作,数据都是共享的,多个不同的 SqlSession 可以共用二级缓存,MyBatis 二级缓存默认是关闭的,需要使用时可手动开启,二级缓存也可以使用第三方的缓存,比如,使用 Ehcache 作为二级缓存。

7.mybatis 和 hibernate 的区别有哪些?
MyBatis 和 Hibernate 都是非常优秀的 ORM 框架,它们的区别如下:
灵活性:MyBatis 更加灵活,自己可以写 SQL 语句,使用起来比较方便;
可移植性:MyBatis 有很多自己写的 SQL,因为每个数据库的 SQL 可以不相同,所以可移植性比较差;
开发效率:Hibernate 对 SQL 语句做了封装,让开发者可以直接使用,因此开发效率更高;
学习和使用门槛:MyBatis 入门比较简单,使用门槛也更低

8.mybatis 有哪些执行器(Executor)?
simpleexecutor执行器:在每执行一次update或select,就开启一个statement对象,用完后就关闭。
reuseexecutor执行器:在执行update或select时以sql作为key去查找statement,有就直接使用,没有就创建,使用完毕后不关闭,放入Map<String,Statement>中,供下次使用。重复使用statement。
batchexecutor执行器:执行update(jdbc批处理不支持select),会把所有sql添加到批处理中addbatch();等待统一批处理executorbatch();它缓存了·多个statement,每一个statement都是addbatch(),后等待进行executorbatch()批处理。

9.mybatis 分页插件的实现原理是什么?
Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页。可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

10.mybatis 如何编写一个自定义插件?
实现原理:
MyBatis 自定义插件针对 MyBatis 四大对象(Executor,StatementHandler,ParamentHandler,ResultSetHandler)进行拦截。
Executor :拦截内部执行器,它负责调用StatementHandler 操作数据库,并把结果集通过 ResultSetHandler 进行自动映射,另外它还处理了二级缓存的操作。
StatementHandler :拦截 SQL 语法构建的处理,它是MyBatis 直接和数据库执行 SQL脚本的对象,另外它也实现了 MyBatis一级缓存
ParamenterHandler :拦截参数的处理。
ResultSetHandler :拦截结果集的处理。
实现关键:
MyBatis 插件要实现 Interceptor 接口,接口包含的方法,如下:
public interface Interceptor {
Object intrceptor(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
setProperties() 方法是在 MyBatis 进行配置插件的时候可以配置自定义相关属性,即:接口实现对象的参数配置。
plugin() 方法是插件用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理,可以决定是否要进行拦截,进而决定要返回一个什么样的目标对象。
interceptor() 方法就是要进行拦截的时候要执行的方法。

11.如何设置 Ehcache 为 MyBatis 的二级缓存?
可直接在 XML 中配置开启 EhcacheCache,代码如下:









<select id="findById" parameterType="java.lang.Long" resultType="com.interview.entity.Classes">
    select * from classes where id = #{id}
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值