我正在参与掘金创作者训练营第5期,点击了解活动详情
本文知识点简介
- 对mybatis的理解
- mybatis的缓存机制
- 怎么分页
- sql注入
- ${}和#{}的区别
唉 大早上的就被催促着起床学习 那不得准备准备给他制造点麻烦?
于是,花了一上午的时间恶补了下mybatis的相关知识,然后考考他。
那么,面试battle开始。。。
我:
谈谈你对mybatis的理解
强哥:
- 首先他是一个轻量级的持久层框架
- 可以自定义sql,存储过程和高级映射
我:
了解mybatis的缓存机制么,详细聊聊
强哥:
mybatis的缓存有两个缓存,一级缓存和二级缓存。
- 一级缓存
- 一级缓存是sqlsession级别的,缓存只有在同一个sqlsession下面才是有效的。缓存没有过期时间,达到一些失效场景时会自动失效
- 至于一级缓存失效的场景
- 不同的sqlsession对应着不同的缓存
- 同一个sqlsession查询条件不同缓存肯定不一样了
- 同一个sqlsession两次查询期间进行了一次增删改操作
- 同一个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时,就只能用这种字符串的替换