Mybatis面试合集

时间: 2023-07-18 admin 互联网

Mybatis面试合集

Mybatis面试合集

目录

一:什么是mybatis

二:Mybaits的优缺点

三:#{} 和 ${}的区别

四:mybatis是什么时候把#{}替换成 ? 的

五:Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

六:Mybatis的一级缓存和二级缓存

七:动态sql

八:模糊查询like语句该怎么写?

九:mybatis如何去自定义主键策略

1、selectKey 标签作用1:获取自增主键

2、selectKey 标签作用2:自定义主键的生成方式

3、selectKey 标签属性介绍

4、selectKey 标签与 useGeneratedKeys、keyProperty 属性

一:什么是mybatis

(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。

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

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

(4)由于MyBatis专注于SQL本身,灵活度高,所以比较适合对性能的要求很高,或者需求变化较多的项目,如互联网项目。

二:Mybaits的优缺点

(1)优点:

① 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;

② 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

③ 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。

④ 能够与Spring很好的集成;

⑤ 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

(2)缺点:

① SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

② SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

三:#{} 和 ${}的区别

${}是字符串替换,#{}是预处理;使用#{}可以有效的防止SQL注入,提高系统安全性。

Mybatis在处理${}时,就是把${}直接替换成变量的值。而Mybatis在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

  • #{}:编译好SQL后语句再去取值
  • ${}:取值以后再去编译SQL语句

四:mybatis是什么时候把#{}替换成 ? 的

1、流程

  • #{}:动态解析 -> 预编译 -> 执行
  • ${}:动态解析 -> 编译 -> 执行

2、案例
根据用户名name查询用户表user数据,如果 name 的值为 zhangsan
#{}

select * from user where name = #{name};

${}

select * from user where name = ${name};

(2)(预)编译中的处理
#{}:在预处理时,会把参数用一个占位符" ?" 代替,变成以下SQL

select * from user where name = ?;

${}:只是简单的字符串替换,在动态解析时变成以下SQL

select * from user where name = 'zhangsan';

当然了,最后的解析结果是一样的,都是

select * from user where name = 'zhangsan';
 

五:Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;原因就是namespace+id是作为Map的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。

备注:在旧版本的Mybatis中,namespace是可选的,不过新版本的namespace已经是必填项了。
 

六:Mybatis的一级缓存和二级缓存

区别:

  • 一级缓存的作用域是一个sqlsession内;
  • 二级缓存作用域是针对mapper进行缓存;

一级缓存:

在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。

二级缓存:

二级缓存的作用域是mapper的同一个namespace。二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的。

七:动态sql

 Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断 并动态拼接sql的功能。Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。
标签使用例子

八:模糊查询like语句该怎么写?

第1种:在Java代码中添加sql通配符。

    string wildcardname = “%smi%”;
    list<name> names = mapper.selectlike(wildcardname);
 
    <select id=”selectlike”>
     select * from foo where bar like #{value}
    </select>
第2种:在sql语句中拼接通配符,会引起sql注入

    string wildcardname = “smi”;
    list<name> names = mapper.selectlike(wildcardname);
 
    <select id=”selectlike”>
         select * from foo where bar like "%"${value}"%"

九:mybatis如何去自定义主键策略

有时候新增一条数据不仅仅要知道是否插入成功,因为后面的逻辑可能还需要这条新增数据的主键,这时候可以使用selectKey 标签获取自增主键,从而避免再次查询数据库。另外,有些业务需要自定义数据表的主键,这个时候也可以使用selectKey 标签来实现,它可以随意的设置生成主键的方式。

1、selectKey 标签作用1:获取自增主键

通常情况下,新增一条数据信息,其主键ID是数据库自动生成的,一般采用自增的形式。selectKey 标签可以获取这个生成的主键。如下所示:

  • <insert id="addUser" parameterType="cn.mybatis.entity.User">
  • <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
  • select LAST_INSERT_ID()
  • </selectKey>
  • insert into t_user(name,sex,phone) values (#{name},#{sex},#{phone})
  • </insert>
 
  • UserDao.add(user);
  • Integer userId = user.getId();
  • System.out.println("新增用户的id为:" + userId);

selectKey 标签的作用:首先在数据库插入user对象,然后执行 select LAST_INSERT_ID()获取数据库里自动生成的主键,最后赋值给user对象的id属性。

2、selectKey 标签作用2:自定义主键的生成方式

除了自动生成主键以外,有些业务需要自定义数据表的主键,这个时候也可以使用selectKey 标签来实现,如下所示:

  • <insert id="addUser" parameterType="cn.mybatis.entity.User">
  • <selectKey resultType="string" order="BEFORE" keyProperty="id">
  • select uuid()
  • </selectKey>
  • insert into t_user(id,name,sex,phone) values (#{id},#{name},#{sex},#{phone})
  • </insert>

3、selectKey 标签属性介绍

  • keyProperty:对应Java实体类中充当主键的属性名,跟数据库的主键对应;
  • order:取值 AFTER 或者 BEFORE。如上例子所述,AFTER 表示在insert执行之后执行 SELECT LAST_INSERT_ID() ,多用获取自增主键;BEFORE 表示在insert执行之前执行select uuid(),适合那种主键不是自增的情况,实现自定义主键。
  • resultType:主键类型

4、selectKey 标签与 useGeneratedKeys、keyProperty 属性

其实,获取自增主键的方式除了使用selectKey 标签以外,还可以使用useGeneratedKeys、keyProperty 属性,可以参考:MyBatis keyProperty 属性介绍,相对来说,后者更简洁。