简单battle下mybatis

104 阅读1分钟

我正在参与掘金创作者训练营第5期,点击了解活动详情

本文知识点简介

  • 对mybatis的理解
  • mybatis的缓存机制
  • 怎么分页
  • sql注入
  • ${}和#{}的区别

image.png

唉 大早上的就被催促着起床学习 那不得准备准备给他制造点麻烦?

于是,花了一上午的时间恶补了下mybatis的相关知识,然后考考他。

image.png

那么,面试battle开始。。。

我:

谈谈你对mybatis的理解

强哥:

  • 首先他是一个轻量级的持久层框架
  • 可以自定义sql,存储过程和高级映射

我:

了解mybatis的缓存机制么,详细聊聊

强哥:

mybatis的缓存有两个缓存,一级缓存和二级缓存。

  • 一级缓存
    • 一级缓存是sqlsession级别的,缓存只有在同一个sqlsession下面才是有效的。缓存没有过期时间,达到一些失效场景时会自动失效
    • 至于一级缓存失效的场景
      1. 不同的sqlsession对应着不同的缓存
      2. 同一个sqlsession查询条件不同缓存肯定不一样了
      3. 同一个sqlsession两次查询期间进行了一次增删改操作
      4. 同一个sqlsession两次查询期间手动清空了缓存
  • 二级缓存
    • 二级缓存是放在命名空间里,也就是sqlSessionFactory级别的,默认是不开启的。
    • 下面介绍二级缓存开启的条件
      • 在核心配置文件中,设置全局 配置属性CacheEnable="true",默认为true,不需要设置
      • 在每个mapper.xml中设置标签
      • 必须在sqlsession关闭或提交时,查询的数据才会缓存到二级缓存中
      • 查询的数据转换对象必须要实现序列化接口
    • 当然二级缓存也会失效
      • 只有当两次查询期间进行了一次增删改操作,二级缓存就会被清空

我:

平常工作中的分页怎么做的

强哥:

我们都知道,分页的sql一般都会这样写(基于mysql)

select * from student limit 0,10

所以其实无论用什么去实现分页都离不开这样的sql

一般用两种方法:

  • 项目自己封装一个分页对象,查询的时候直接传入分页对象即可
  • 使用分页插件,至于插件的实现,下次再聊

我:

sql注入是啥,怎么避免sql注入

强哥:

简单来讲,就是在执行sql的过程中,传入非法的字符去破坏原有的sql结构。造成数据返回结果有误问题,严重可能导致数据库数据直接被删除,举个例子。

delete from user where name = "${name}"

当我们name值传入"'强哥' or 1 = 1"

最终sql执行就是:

delete from user where name = '强哥' or 1 = 1

这样的sql注入结果很明显了,会删除表里所有的数据。所以在实际生成中,尽量避免sql注入,否则会导致很严重的结果

至于怎么避免sql注入,我们得先弄明白${}和#{}的区别

  • ${}就是个占位符,实际上就是字符串的替换
  • #{}会进行预编译处理,会先将#{}替换为?,然后通过调用PreparedStatement的set方法来赋值;而取出来的值会给他添加''拼接sql

继续上面的例子

delete from user where name = "${name}"
delete from user where name = "#{name}"

如果是下面的sql,最终执行的语句就是
delete from user where name = "'强哥' or 1 = 1"

那自然就没有sql注入的问题了

那么,照这样说,${}是不是就没啥用啦,其实不然,当我们要数据库字段作为参数拼接sql时,就只能用这种字符串的替换