面试宝典之mybatis与mybatis-plus面试题

Mybatis:

一、请说说在Mybatis 中#和$有什么区别?

#相当于对数据 加上 双引号,$相当于直接显示数据

  1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成 sql 时的值为 order by "111", 如果传入的值是 id,则解析成的 sql 为 order by "id".

  2. 将传入的数据直接显示生成在 sql 中。如:order by user_id$,如果传入的值是 111,那么解析成 sql 时的值为order by user_id, 如果传入的值是 id,则解析成的 sql 为 order by id.

  3. #方式能够很大程度防止 sql 注入。

4.$方式无法防止 Sql 注入。

5.$方式一般用于传入数据库对象,例如传入表名.

6.一般能用#的就别用$.

二、说说在使用JDBC 编程时,它有哪些不足之处,MyBatis 是如何解决这些问题的?
  1. 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。

解决:在 SqlMapConfig.xml 中配置数据连接池,使用连接池管理数据库连接。

  1. Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。

  1. 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数一一对应。

解决: Mybatis 自动将 java 对象映射至 sql 语句。

  1. 对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对象解析比较方便。

解决:Mybatis 自动将 sql 执行结果映射至 java 对象。

三、请你说一下使用 MyBatis 的 mapper 接口调用时有哪些要求?
  1. Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同

  2. Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同

  3. Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同

  4. Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。

四、你知道Mybatis 中一级缓存与二级缓存吗?
  1. 一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或close 之后,该 Session 中的所有 Cache 就将清空。

  2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为Mapper(Namespace),并且可自定义存储源,如 Ehcache。

作用域为 namespance 是指对该 namespance 对应的配置文件中所有的 select 操作结果都缓存,这样不同线程之间就可以共用二级缓存。

启动二级缓存:在 mapper 配置文件中:<cache />。

二级缓存可以设置返回的缓存对象策略:<cache readOnly="true">。当 readOnly="true"时,表示二级缓存返回给所有调用者同一个缓存对象实例,调用者可以 update 获取的缓存实例,

但是这样可能会造成其他调用者出现数据不一致的情况(因为所有调用者调用的是同一个实例)。

当 readOnly="false"时,返回给调用者的是二级缓存总缓存对象的拷贝,即不同调用者获取的是缓存对象不同的实例,这样调用者对各自的缓存对象的修改不会影响到其他的调用者,即是安全的,所以默认是 readOnly="false";

  1. 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
五、MyBatis 在 insert 插入操作时返回主键 ID

1、数据库为 MySql 时:

<insert id="insert" parameterType="com.test.User" keyProperty="userId"

useGeneratedKeys="true" >

keyProperty"表示返回的 id 要保存到对象的那个属性中,"useGeneratedKeys"表示主键 id 为自增长模式。

2、MySQL 中做以上配置就 OK 了

数据库为 Oracle 时:

java 复制代码
<insert id="insert" parameterType="com.test.User">

<selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">

SELECT SEQ_USER.NEXTVAL as userId from DUAL

</selectKey>

insert into user (user_id, user_name, modified, state)

values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR},

#{modified,jdbcType=TIMESTAMP}, #{state,jdbcType=INTEGER})

</insert>

由于 Oracle 没有自增长一说法,只有序列这种模仿自增的形式,所以不能再使用"useGeneratedKeys"属性。而是使用<selectKey>将 ID 获取并赋值到对象的属性中,insert 插入操作时正常插入 id。

六、说一说使用Mybatis开发的时候,步骤是什么样的?

1、创建 SqlSessionFactory

2、通过 SqlSessionFactory 创建 SqlSession

3、通过 sqlsession 执行数据库操作

4、调用 session.commit()提交事务

5、调用 session.close()关闭会话

Mybatis-plus

一:MyBatis-Plus是什么?它有什么优点?

MyBatis-Plus是MyBatis框架的一个扩展库,它提供了一系列方便的API和工具,可以简化常见的数据库操作。MyBatis-Plus的优点包括:

  • 提高开发效率:MyBatis-Plus提供了代码生成、分页、查询构建等功能,可以帮助开发人员快速开发数据库相关的功能。
  • 简化操作:MyBatis-Plus提供了一些常用的API和工具,可以简化CRUD操作、批量操作等常见的数据库操作。
  • 提高代码可读性:MyBatis-Plus提供了一些Lambda表达式的API,可以使代码更加简洁易读。

二:MyBatis-Plus的主要API有哪些?

MyBatis-Plus的主要API包括:

  • QueryWrapper:用于构建查询条件。
  • UpdateWrapper:用于构建更新条件。
  • LambdaQueryWrapper:用于构建Lambda表达式查询条件。
  • LambdaUpdateWrapper:用于构建Lambda表达式更新条件。
  • Page:用于分页查询。
  • EntityWrapper:用于根据实体类属性构建查询条件。

三:MyBatis-Plus的代码生成器是如何使用的?

MyBatis-Plus的代码生成器可以帮助开发人员快速生成常用的代码,例如entity、mapper、service和controller等。使用代码生成器的步骤如下:

  • 在pom.xml中添加mybatis-plus-generator的依赖。
  • 编写代码生成器的配置文件generatorConfig.xml。
  • 运行代码生成器,生成对应的代码。

四:MyBatis-Plus的分页功能是如何实现的?

MyBatis-Plus的分页功能通过Page类实现,使用方法如下:

  • 构建Page对象,设置当前页码和每页显示的记录数。
  • 调用MyBatis-Plus提供的分页查询方法,将Page对象作为参数传入。
  • MyBatis-Plus会自动将查询结果封装到Page对象中,并返回给调用方。

五:MyBatis-Plus的查询构建功能是如何实现的?

MyBatis-Plus的查询构建功能通过QueryWrapper、UpdateWrapper、LambdaQueryWrapper等类实现,使用方法如下:

  • 创建对应的Wrapper对象。
  • 使用Wrapper提供的API构建查询条件或更新条件。
  • 将Wrapper对象作为参数传入对应的查询或更新方法中。

六:MyBatis-Plus和MyBatis有什么区别?

MyBatis-Plus是MyBatis的一个扩展库,它在MyBatis的基础上提供了一些方便的API和工具,可以简化常见的数据库操作。相比于MyBatis,MyBatis-Plus具有更加简洁的语法和更高的开发效率。

七:MyBatis-Plus的分页查询和原始的分页查询有什么区别?

MyBatis-Plus的分页查询使用了数据库的分页查询语句,可以大大提高查询效率。相比于原始的分页查询,MyBatis-Plus的分页查询更加简单方便,可以自动计算总记录数等信息。

具体区别:

MyBatis-Plus 的分页查询相比于原始的分页查询有以下几点区别:

  1. 更加简单易用:MyBatis-Plus 的分页查询非常简单,只需要使用 Page 类、IPage 接口和 selectPage 方法等少量 API 即可实现分页查询,而且不需要手动计算分页参数。
  2. 更加灵活:MyBatis-Plus 的分页查询支持多种分页方式,包括基于物理分页和基于逻辑分页,开发者可以根据实际需求选择合适的分页方式。
  3. 更加高效:MyBatis-Plus 的分页查询使用了物理分页的优化方式,可以减少数据库的 IO 操作和内存消耗,提高查询效率。
  4. 更加可维护:MyBatis-Plus 的分页查询支持自动生成代码,可以减少手动编写 SQL 语句的工作量,提高代码的可维护性。
代码示例

|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| > 1 > 2 > 3 > 4 > 5 > 6 > 7 > 8 | // 创建 Page 对象,指定当前页码和每页显示的数量 Page<User> page = ``new Page<>(``1``, ``10``); // 调用 selectPage 方法查询分页数据 IPage<User> userPage = userMapper.selectPage(page, ``null``); // 获取分页数据 List<User> userList = userPage.getRecords(); |

在上面的示例中,首先创建了一个 Page 对象,指定了当前页码为 1,每页显示的数量为 10。然后,调用 selectPage 方法,将 Page 对象和一个查询条件作为参数传入,这个方法会返回一个 IPage<User> 对象,其中包含了符合条件的所有用户数据以及分页信息。最后,可以通过 getRecords 方法获取分页数据。

八:MyBatis-Plus的Wrapper类是如何实现动态查询的?

MyBatis-Plus的Wrapper类提供了一系列的方法,可以根据需要动态构建查询条件。

例如, eqnelikebetween。可以使用eq方法构建等于条件,使用gt方法构建大于条件等。

在构建查询条件时,可以根据需要动态添加或删除查询条件,从而实现动态查询的功能。

Wrapper 类的实现原理是在运行时动态生成 SQL 语句,根据传入的条件动态拼接 SQL 语句,然后使用 MyBatis 的 SQL 解析器解析生成的 SQL 语句,最终执行 SQL 查询操作。这种方式可以避免手写 SQL 语句导致的 SQL 注入问题,并且可以使代码更加易于维护和扩展。

下面是一个简单的示例,展示了如何使用 Wrapper 类实现动态查询:

|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| > 1 > 2 > 3 > 4 > 5 > 6 > 7 > 8 > 9 > 10 > 11 > 12 > 13 | // 创建 Wrapper 对象 QueryWrapper<User> wrapper = ``new QueryWrapper<>(); // 动态添加查询条件 if (StringUtils.isNotBlank(username)) { ``wrapper.eq(``"username"``, username); } if (StringUtils.isNotBlank(email)) { ``wrapper.eq(``"email"``, email); } // 执行查询操作 List<User> userList = userMapper.selectList(wrapper); |

在上面的示例中,首先创建了一个 QueryWrapper 对象,然后根据需要动态添加了查询条件。

最后,调用 selectList 方法执行查询操作,将 QueryWrapper 对象作为参数传入。

这样就可以根据动态生成的查询条件查询出符合条件的用户数据了。

九:MyBatis-Plus的LambdaQueryWrapper和QueryWrapper有什么区别?

LambdaQueryWrapper和QueryWrapper都是MyBatis-Plus提供的用于构建查询条件的类。LambdaQueryWrapper使用Lambda表达式来构建查询条件,代码更加简洁易读。QueryWrapper使用传统的方法来构建查询条件,更加灵活。一般来说,如果项目中使用了Java 8及以上版本,建议使用LambdaQueryWrapper来构建查询条件。

十:MyBatis-Plus的代码生成器可以自定义模板吗?

是的,MyBatis-Plus的代码生成器可以自定义模板。在使用代码生成器时,可以指定自定义的模板,从而生成符合项目需求的代码。自定义模板需要遵循FreeMarker语法,可以根据需要修改模板内容。

相关推荐
一只叫煤球的猫5 小时前
写代码很6,面试秒变菜鸟?不卖课,面试官视角走心探讨
前端·后端·面试
bobz9655 小时前
tcp/ip 中的多路复用
后端
bobz9655 小时前
tls ingress 简单记录
后端
皮皮林5516 小时前
IDEA 源码阅读利器,你居然还不会?
java·intellij idea
你的人类朋友6 小时前
什么是OpenSSL
后端·安全·程序员
bobz9657 小时前
mcp 直接操作浏览器
后端
前端小张同学9 小时前
服务器部署 gitlab 占用空间太大怎么办,优化思路。
后端
databook9 小时前
Manim实现闪光轨迹特效
后端·python·动效
武子康10 小时前
大数据-98 Spark 从 DStream 到 Structured Streaming:Spark 实时计算的演进
大数据·后端·spark
该用户已不存在10 小时前
6个值得收藏的.NET ORM 框架
前端·后端·.net