MyBtais面试题

一、介绍一下MyBatis

MyBatis 是一款优秀的持久层框架(ORM对象映射关系框架)

  • 支持自定义 SQL、存储过程以及高级映射
  • 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作
  • 通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录

1.1.持久化:数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库(jdbc):io文件持久化

为什么要持久化?

  • 有一些对象不能让他丢掉
  • 内存太贵了

1.2.持久层
Dao层、Service层、Controller层

  • 完成持久化工作的代码块
  • 层界限十分明显

1.4.为什么需要Mybatis?

  • 方便
  • 传统的JDBC代码太复杂了。
  • 优点:可以在 XML 或注解中直接编写 SQL 语句,比较灵活,方便对 SQL 的优化与调整
  • XML 中提供了动态 SQL 的标签,方便根据条件拼接 SQL
  • 提供了 XML、注解与 Java 对象的映射机制(注解实现原理

二、#{} 和 ${}的区别

  • MyBatis 在处理 #{} 时,会将 SQL 中的 #{} 替换为 ?,预编译 SQL,通过 PreparedStatement 的setXxxx 的方法进行参数赋值。使用 #{} 可以有效地防止 SQL 注入。

#传入的参数在SQL中显示为字符串,#方式能够很大程度防止sql注入;$ 传入的参数在SqL中直接显示为传入的值,$方式无法防止Sql注入。

下面我们来看一下一种简单的注入,如果我们在表单中username的输入框中输入’ or 1=1-- ,password的表单中随便输入一些东西,假如这里输入123.此时我们所要执行的sql语句就变成了select id from users where username = ‘’ or 1=1-- and password = ‘123’,我们来看一下这个sql,因为1=1是true,后面 and password = '123’被注释掉了。所以这里完全跳过了sql验证。

三、MyBatis 中如何配置连接中断或执行超时?

Mybatis 的 XML 配置中,在 节点中添加子节点 ,name=defaultStatementTimeout,设置等待数据库响应的超时时间。

<settings>
  <!-- 设置超时时间,它决定数据库驱动等待数据库响应的秒数 -->
  <setting name="defaultStatementTimeout" value="25"/>
</settings>

四、Mybatis的一级缓存和二级缓存缓存及配置

一级缓存

SqlSession级别,也叫本地缓存,默认开启,只要在同一个SqlSession中,执行相同的查询语句,并且查的是同一个mapper.xml文件,那么会走一级缓存,SqlSession会话关闭的话,一级缓存就失效了。

在这里插入图片描述
上面的例子中,由于查询的都是id为1的用户,执行的sql语句也是一模一样的,并且是在同一个SqlSession中执行的,那么会走缓存。
在这里插入图片描述
上面的例子中,第二次查询id为1的用户是不走缓存的,因为增删改操作都会导致缓存失效,即使改的数据跟我们查的数据无关

一级缓存失效的情况:

  • 查询不同的东西(sql语句必须一模一样才会走缓存)
  • 增删改操作
  • 查询不同的Mapper.xml
  • 手动清理缓存(sqlsession.clearCache())
  • SqlSession会话连接关闭

二级缓存

由于一级缓存作用域太低了,所以诞生了二级缓存,二级缓存是基于namespace级别的缓存,也就是一个命名空间,或者叫一个mapper.xml文件,对应一个二级缓存;开启二级缓存只需要在对应的mapper.xml文件声明一个 标签
在这里插入图片描述
上面这个例子应该是不走缓存的,虽然我们开启了二级缓存,但是由于二级缓存的工作机制是:SqlSession关闭时,一级缓存失效,才会将一级缓存中的东西放到二级缓存中,上面的例子由于sqlSession2执行查询的时候,sqlSession还未关闭,所以二级缓存中没有对应的缓存信息
在这里插入图片描述

如果是这个执行顺序的话,那么就会走缓存了

二级缓存小结: 只要开启了二级缓存,在同一个Mapper.xml文件下就能生效;所有的数据都会先放在一级缓存中,只有当会话提交,或者会话关闭的时候,才会提交到二级缓存中。

附:二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。

Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

开启二级缓存

在这里插入图片描述

缓存的执行顺序
在这里插入图片描述
二级缓存的缺陷:此处

对于Sqlession此文链接:SqlSession原理

mybatis操作的时候跟数据库的每一次连接,都需要创建一个会话,我们用openSession()方法来创建。这个会话里面需要包含一个Executor用来执行 SQL
一切Mybatis配置都是为了创建SqlSession进行SQL查询;

五、MyBatis 如何批量插入?

方式一、打开批量插入的 SqlSession

SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
for (int i = 36; i <= 45; i++) {
    
    
    userMapper.insertUser(new User(i, "ConstXiong" + i));
}
sqlSession.commit();
sqlSession.close();

方式二、拼接批量插入的 insert SQL

//Java 代码
List<User> userList = new ArrayList<>();
for (int i = 46; i <= 55; i++) {
    
    
    userList.add(new User(i,"ConstXiong" + i));
}
userMapper.insertUserBatch(userList);

<!--Mapper xml 中配置-->
<insert id="insertUserBatch" parameterType="java.util.List">
    insert into user values
    <foreach collection="list" item="item" separator =",">
        (#{
    
    item.id}, #{
    
    item.name})
    </foreach>
</insert>

六、Mybatis的xml文件中,sql语句可以使用直接使用大于号小于号吗?应该用什么符号代替?

小于号 < 用 <
大于号 > 用 >
和 & 用 &
单引号 ’ 用 ’
双引号 " 用 "

猜你喜欢

转载自blog.csdn.net/weixin_42754971/article/details/114302641
今日推荐