【Java面试题】框架篇——MyBatis

MyBatis架构图★★★

在这里插入图片描述

1、 mybatis配置

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

MyBatis常见注解★★★

MyBatis是一个Java持久化框架,它提供了一些注解来简化SQL语句的编写和映射。以下是一些常用的MyBatis注解及其作用:

1. @Select:用于标记一个查询方法。

2. @Update:用于标记一个更新方法。

3. @Insert:用于标记一个插入方法。

4. @Delete:用于标记一个删除方法。

5. @Results:用于指定查询结果的映射关系。

6. @ResultMap:用于指定查询结果的映射关系,可以对查询结果进行进一步的映射处理。

7. @Param:用于指定SQL语句中的参数名称。

8. @Options:用于指定执行SQL语句时的选项,如缓存、事务等。

9. @Where:用于标记查询条件。

10. @OrderBy:用于标记查询结果的排序规则。

这些注解可以帮助开发人员快速构建MyBatis应用程序,并使其更加易于维护和扩展。同时,MyBatis还提供了许多其他注解和配置文件,可以根据具体需求进行选择和使用。

Mapper代理开发规范★★★

​ Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。

2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

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

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

MyBatis一级缓存和二级缓存★★★

在这里插入图片描述

一级缓存是默认开启的,二级缓存默认关闭。

  • 作用范围

    • 一级缓存是会话级别的缓存,即sqlSession级别,会话结束,清除会话中的缓存数据,实际代码中通过通过开启事务让多个数据库操作共享一个sqlSession。
    • 二级缓存: 全局级别,也叫namespace级别,会话结束,缓存依然存在,多个请求可以共享缓存数据。
  • 缓存位置

    • 一级缓存由于是sqlSession级别,本质上是在JVM中创建一个Map集合对象保存缓存数据,所以缓存数据保留的地方是本地JVM内存中。
    • 二级缓存默认也是保存在JVM中,但是可以通过配置将缓存数据保存到第三方缓存中,比如ehcache、redis。保存在redis这些的分布式缓存中,能提供更好的分布式场景的支持。
  • 缓存过期

    • 一级缓存无过期时间,只有生命周期,缓存会先放在一级缓存中,当sqlSession会话提交或者关闭时才会将一级缓存刷新到二级缓存中;开启二级缓存后,用户查询时,会先去二级缓存中找,找不到在去一级缓存中找,然后才去数据库查询;
    • 二级缓存的过期时间默认是1小时,如果这个cache存活了一个小时,那么将整个清空一下。需要注意的是,并不是key-value的过期时间,而是这个cache的过期时间,是flushInterval,意味着整个清空缓存cache,所以不需要后台线程去定时检测,每当存取数据的时候,都有检测一下cache的生命时间。

一级缓存的作用在我看来在实际业务场景中作用真的非常有限,因为需要在一个事务方法中重复查询的需求场景真的太少,而且由于Mysql数据库的MVCC机制以及事务隔离机制-可重复读的能力,会导致同一个事务方法内多次执行相同的查询必定会得到相同的结果,所以在事务范围内的重复查询基本没什么实际作用。
设计一级缓存设计的意义,可能更多的是为二级缓存的实现做铺垫。
所以,如果关闭了mybatis的一级缓存,二级缓存将不会生效。

MyBatis-Plus注解

MyBatis-Plus是MyBatis的一个增强工具,它提供了许多注解和API来简化开发。以下是一些常用的MyBatis-Plus注解及其作用:

1. @Select:用于标记一个查询方法。
2. @Update:用于标记一个更新方法。
3. @Insert:用于标记一个插入方法。
4. @Delete:用于标记一个删除方法。
5. @BatchInsert:用于批量插入数据。
6. @TableField:用于指定实体类中的字段与数据库表中的字段映射关系。
7. @TableName:用于指定查询的数据库表名。
8. @Version:用于添加版本号字段。
9. @LogicDelete:用于标记逻辑删除字段。
10. @TableId:用于自动生成主键。

这些注解可以帮助开发人员快速构建MyBatis-Plus应用程序,并使其更加易于维护和扩展。同时,MyBatis-Plus还提供了许多其他注解和API,可以根据具体需求进行选择和使用。

MyBatisplus分页是如何实现的?

MyBatis-Plus是一个基于MyBatis的增强工具,它提供了一些便捷的CRUD操作和分页查询功能。在分页查询方面,MyBatis-Plus采用了以下两种方式:

1. 使用数据库原生的分页查询(如MySQL中的LIMIT、OFFSET):

MyBatis-Plus会根据Mapper接口中定义的方法参数,自动生成SQL语句,并将查询结果封装成Page对象返回给调用者。例如,假设Mapper接口中有以下方法:

public interface UserMapper extends BaseMapper<User> {
    List<User> selectUsersWithPage(int pageNum, int pageSize);
}

那么对应的SQL语句就是:

SELECT * FROM user LIMIT ? OFFSET ?

其中,pageNum和pageSize是传入的参数,用于指定要查询的页数和每页的数据条数。调用上述方法即可实现分页查询:

Page<User> page = new Page<>(pageNum, pageSize);
List<User> users = userMapper.selectUsersWithPage(pageNum, pageSize);
page.setRecords(users);
return page;


1. 自定义分页插件:

如果需要更加灵活地控制分页查询的实现方式,可以使用自定义分页插件。MyBatis-Plus提供了一个PaginationInterceptor拦截器,可以用于拦截SQL执行过程中的分页操作。通过继承PaginationInterceptor并重写相应的方法,可以实现自定义的分页逻辑。

Mybatis动态SQL如何实现

Mybatis动态SQL可以通过两种方式实现:

1. 使用if、choose、when、otherwise等标签进行条件判断和分支处理,例如:
<select id="selectUser" resultType="User">
  select * from user
  <where>
    <if test="username != null">
      and username like #{username}%
    </if>
  </where>
</select>


1. 使用foreach标签遍历集合或数组,并根据元素的属性值动态拼接SQL语句,例如:
<select id="selectUserByIdList" resultType="User">
  select * from user where id in
  <foreach collection="idList" item="id" open="(" close=")">
    #{id}
  </foreach>
</select>


在第二种方式中,需要注意以下几点:

  • foreach标签中的item属性表示当前循环迭代的对象,open属性表示开始拼接字符串时使用的符号,close属性表示结束拼接字符串时使用的符号。
  • 如果遍历的集合或数组比较大,建议将其中的属性值转换为Java对象的属性名,以提高SQL语句的可读性和性能。

MyBatis 使用了哪些设计模式?★★★

在 MyBatis 中,常见的设计模式有以下几种:

1. 工厂模式(Factory Pattern):MyBatis 中的 SqlSessionFactoryBuilder、SqlSessionFactory 等都是工厂模式的典型应用。

2. 单例模式(Singleton Pattern):MyBatis 中的 Configuration、SqlSessionFactory 等都是单例模式的应用。

3. 代理模式(Proxy Pattern):MyBatis 中的 Mapper 接口和映射文件都是代理模式的应用。Mapper 接口是被代理的对象,而映射文件则是代理的方式。

4. 装饰器模式(Decorator Pattern):MyBatis 中的 ResultHandler、Executor、StatementHandler 等都是装饰器模式的应用。

5. 观察者模式(Observer Pattern):MyBatis 中的 SqlSessionListener 接口就是观察者模式的应用。当 MyBatis 的 SqlSession 状态发生变化时,会触发相应的回调方法。

总之,MyBatis 在实现过程中使用了很多常见的设计模式,这些设计模式使得 MyBatis 能够更加灵活、高效地完成任务。

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

在 MyBatis 中,#{}${} 都是用来占位的语法,但它们的作用范围和使用方式有所不同。

1. `#{}` 占位符:用于绑定参数值到 SQL 语句中的占位符。它可以绑定基本类型、Java 对象、Map 等数据类型。例如:
SELECT * FROM users WHERE username = #{username} AND password = #{password}
2. `${}` 占位符:用于绑定常量值到 SQL 语句中的占位符。它只能绑定常量值,不能绑定动态数据。例如:
SELECT * FROM users WHERE age = ${age} AND gender = #{gender}

总之,#{}${} 在 MyBatis 中都是占位符,但它们的作用范围和使用方式有所不同。#{} 可以绑定任意类型的数据,而 ${} 只能绑定常量值。

MyBatis 中实体类中的属性名和表中的字段名不一样 ,怎么办 ?

在 MyBatis 中,实体类中的属性名和表中的字段名不一致时,可以使用 @Param 注解来指定参数名称。例如:

public class User {
    @Id
    private Long id;
    
    @Column(name = "user_name")
    private String userName;
    
    @Column(name = "age")
    private Integer age;
    
    // ... 其他属性
}

public interface UserMapper {
    @Select("SELECT * FROM users WHERE user_name = #{userName} AND age = #{age}")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int getUserByNameAndAge(@Param("userName") String userName, @Param("age") Integer age);
}

在上面的例子中,@Column 注解中的 name 属性与实体类中的属性名不同,但我们可以通过指定 @Param 注解的参数名称来解决这个问题。这样,MyBatis 就能够正确地将参数绑定到 SQL 语句中的占位符上。

说说MyBatis的优点和缺点

MyBatis 是一款优秀的持久层框架,具有以下优点:

1. 灵活性高:MyBatis 支持自定义 SQL、动态 SQL、存储过程等,能够满足各种复杂的数据库操作需求。

2. 易于学习和使用:MyBatis 的 API 简单易懂,文档详细,学习成本较低。同时,MyBatis 还提供了强大的插件机制,可以方便地扩展和定制功能。

3. 性能优秀:MyBatis 的 SQL 解析和执行效率较高,能够提高应用程序的性能和响应速度。

4. 与 Spring 集成紧密:MyBatis 与 Spring 框架集成紧密,可以方便地进行数据访问和业务逻辑处理。

然而,MyBatis 也存在一些缺点:

1. XML 配置繁琐:MyBatis 需要通过 XML 文件来进行配置,如果 XML 文件写得不好,会导致代码冗长、难以维护。

2. 对 SQL 语句的支持有限:虽然 MyBatis 支持自定义 SQL,但是对于复杂的查询和联表操作,需要编写大量的 SQL 代码,增加了开发难度和维护成本。

3. 对于大型项目的支持不够完善:由于 MyBatis 采用的是基于 XML 的配置方式,对于大型项目来说,XML 文件会变得非常庞大,不易维护和更新。

总之,MyBatis 具有灵活性强、易于学习和使用、性能优秀等优点,但也存在 XML 配置繁琐、对 SQL 语句的支持有限、对于大型项目的支持不够完善等缺点。在使用 MyBatis 时需要根据具体情况进行权衡和选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wei *

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值