侧边栏壁纸
博主头像
lmg博主等级

  • 累计撰写 55 篇文章
  • 累计创建 6 个标签
  • 累计收到 2 条评论
标签搜索

mybatis面试题

lmg
lmg
2020-05-23 / 0 评论 / 0 点赞 / 314 阅读 / 2,772 字
温馨提示:
本文最后更新于 2022-04-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

MyBatis介绍

  1. 持久层框架,内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。

  2. MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

  3. 通过XML或者注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。

MyBatis和Hibernate的区别

(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。

(2)Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。

(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。

#{}和${}的区别是什么?

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

接口式编程

原生: Dao ==========> DaoImpl

mybatis: Mapper ========> xxMapper.xml

Mapper是一个接口,并没有实现类,而是有一个与之对应得配置文件。这个配置文件就相当于Mapper得实现。

具体过程:mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。(将接口和xml进行绑定)

EmployeeMapper empMapper = sqlSession.getMapper(EmployeeMapper.class);

Mybatis第一天讲义

Mybatis第二天讲义

Mybatis第三天讲义

Mybatis第四天讲义

mybatis参数设置

单个参数: mybatis不会做特殊处理

#{参数名}:取出参数

多个参数:mybatis会做特殊处理,多个参数会被封装成一个map

key: param1...paramN,或者参数的索引也可以

value: 传入的参数值

#就是从map中获取指定的key值

这样写去参数容易眼花缭乱,可以使用

命名参数:明确指定封装参数时map的key:@Param("id")

多个参数会被封装成一个map,

key:使用@Param注解指定的值

value: 参数值

#{指定的key}取出对应的参数值

POJO

如果多个参数正好是业务逻辑的数据模型,我们可以直接传入pojo

#{属性名}: 取出传入的pojo的属性值

Map:

如果多个参数不是业务模型中的数据,没有对应的pojo,为了方便,我们也可以传入map

#: 取出map中对应的值

resultType和resultMap

resultType:当使用resultType做SQL语句返回结果类型处理时,对于SQL语句查询出的字段在相应的pojo中必须有和它相同的字段对应.

resultMap:当使用resultMap做SQL语句返回结果类型处理时,通常需要在mapper.xml中定义resultMap进行pojo和相应表字段的对应。

Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。

第二种是使用sql列的别名功能,将列的别名书写为对象属性名。

有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

动态SQL

if:判断

choose(when,otherwise):分支,选择

foreach遍历

两个内置参数:不只是方法传递过来的参数可以被用来判断,取值。mybatis默认还有两个内置参数

_parameter: 代表整个参数

​ 单个参数:_parameter就是这个参数

​ 多个参数:_parameter就是代表多个参数封装的map

_databaseId: 全局配置了databaseIdProvider标签, _databaseId就是代表当前数据库的别名mysql

sql标签

抽取可重用的sql片段,方便后面引用(使用include标签引用)。

mybatis缓存机制

一级、二级缓存
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

mybatis系统中默认定义了两级缓存:一级缓存,二级缓存。

1.默认情况下,只有一级缓存(SqlSession级别的缓存,也成为本地缓存)开启,只要sqlSession没有flush或close,它就存在 。

2.二级缓存(全局缓存)需要手动开启和配置,他是基于namespace级别的缓存(在XXmapper.xml配置)

3.为了提高拓展性,mybatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存。

一级缓存失效的四种情况

1.sqlSession不同

2.sqlSession相同,查询条件不同

3.sqlSession相同,两次查询之间执行了增删改操作(可能对当前数据有影响)

4.sqlSession相同,手动清空了一级缓存

二级缓存

工作机制

1.一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中

2.如果会话关闭,一级缓存中的数据会被保存在二级缓存中

二级缓存注意事项:所缓存的类一定要序列化,这种就可以使用序列化的方式来保存对象。

查找顺序:二级缓存,一级缓存,数据库

0

评论区