Java知识复习(十六)MyBatis

1、什么是MyBatis

  • Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,加载驱动、创建连接、创建statement等繁杂的过程,开发者开发时只需要关注如何编写SQL语句,可以严格控制sql执行性能,灵活度高。
  • 作为一个半ORM框架,MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集

2、#{}和${}的区别是什么

  • #{}是预编译处理方式,${}是字符串替换方式。在预编译处理方式中,#{}会将传入的参数当做一个占位符,然后在执行SQL语句之前,会使用PreparedStatement预编译SQL语句,将#{}替换为?占位符,最后在执行时,将占位符?的值动态绑定到SQL语句中,避免了SQL注入的问题。而在字符串替换方式中, ${}会将传入的参数直接替换到SQL语句中,容易导致SQL注入的问题。
  • #{}可以防止SQL注入,${}不能。在使用#{}时,MyBatis会自动对参数值进行转义处理,确保SQL语句的安全性,而在使用 ${}时,如果不对参数进行转义处理,就容易被注入恶意SQL语句。
  • #{}可以实现占位符的重用, ${}不能。在使用#{}时,可以在SQL语句中使用多个#{}占位符,然后在传入参数时,将相应的值绑定到每个占位符上。而在使用 ${}时,只能使用一个 ${}占位符,将其替换为传入的参数值。
# 编译前
select name form student where age=#{studentAge};
select name form student where age=${studentAge};

# 编译后
select name form student where age='18';
select name form student where age=18;

注意:sql注入就是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步获取到数据信息

3、MyBatis的一级和二级缓存

  • Mybatis对缓存提供支持,一级缓存是默认使用的,二级缓存需要手动开启。

1、一级缓存:

  • 一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率
  • 需要注意的是,如果SqlSession执行了DML操作(增删改),并且提交到数据库,MyBatis则会清空SqlSession中的一级缓存(执行更新操作的效果),也清空二级缓存(执行commit()的效果),这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象
  • 当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了。关闭一级缓存后,再次访问,需要再次获取一级缓存,然后才能查找数据,否则会抛出异常

2、二级缓存

  • 二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率
  • 二级缓存是mapper级别的缓存。使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。相比一级缓存SqlSession,二级缓存的范围更大,多个Sqlsession可以共用二级缓存,二级缓存是跨SqlSession的

3、eviction收回策略

  • LRU – 最近最少使用的:移除最长时间不被使用的对象。(默认)
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

4、MyBatis是如何进行分页的?分页插件的原理是什么?

  • Mybatis 使用 RowBounds 对象进行分页,也可以直接编写 sql 实现分页(比如limit),也可以使用Mybatis 的分页插件
  • 分页插件的原理:实现 Mybatis 提供的接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql
  • 举例:select * from student,拦截 sql 后重写为:select t.* from (select * from student)limit 0,10

5、MyBatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

  • 当列名和封装查询结果的类的属性名一一对应时,这时MyBatis 有自动映射功能,将查询的记录封装到resultType 指定的类的对象中去
<mapper namespace="com.hanT.dao.UserDao">
    <!--id对应接口中的方法名,resultType为返回结果的类型,要用类的全限定名-->
    <select id="getUserList" resultType="com.hanT.pojo.User">
        select * from mybatis.user
    </select>
</mapper>
  • 当列名和封装查询结果的类的属性名不对应时,可以使用< resultMap >标签,逐一定义数据库列名和对象属性名之间的映射关系。
<resultMap type="cn.com.mybatis.pojo.User" id="UserResult">
    <result property="username" column="name"/>
</resultMap>
<select id="findUserById" parameterType="java.lang.Long" resultMap="UserResult">
    select id,name,email from t_user where id=#{id}
</select>
  • 第二种是使用sql列的别名功能,将列的别名书写为对象属性名,MyBatis 会忽略列名大小写,智能找到与之对应对象属性名(也就是as)
  • 有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

6、MyBatis里面的动态SQL是怎么设定的?有哪些动态SQL标签?

  • Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断 并动态拼接sql的功能。
  • Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。

7、模糊查询like语句怎么写?

  • 在Java代码中添加sql通配符,通过#{}赋值
string wildcardname =%smi%;
list<name> names = mapper.selectlike(wildcardname);
 
<select id=”selectlike”>
select * from foo where bar like #{value}
</select>
  • 在sql语句中拼接通配符,会引起sql注入(不推荐)
string wildcardname = “smi”;
list<name> names = mapper.selectlike(wildcardname);
 
<select id=”selectlike”>
select * from foo where bar like "%"${value}"%"
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值