MyBatis

1. 什么是Mybatis

Mybatis是一款优秀持久层的框架。内部封装了JDBC,开发时只需要关注SQL语句的,不需要花时间精力去加载驱动、创建连接、创建statement、执行sql、处理结果集等过程。MyBatis可以使用xml或者注解来配置和映射原生信息,将java中的pojo对象映射成数据库中的记录。

2.MyBatis的优缺点

  • 优点
  1. 基于sql语句编写代码,与JDBC相比,减少了代码量,消除了JDBC大量的冗余代码
  2. MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持,数据库兼容性很好
  3. 能够与Spring继承
  4. 提供映射标签,可以支持复杂的映射关系处理
  • 缺点
  1. sql语句编写工作量较大

3. #{}和${}的区别

#{}:是预编译处理,能防止sql注入

${}:是字符串替换,一般使用是列名表名,不同排序规则
在这里插入图片描述

4.处理实体类中属性名和表字段不一致问题

  1. 通过sql查询语言定义字段的别名,让字段的别名和实体类的属性名相同
  2. 通过结果集映射将实体类的属性和数据表的字段一一对应

5.MyBatis如何分页的

MyBatis是使用RowBounds对象进行分页,它是正针对ResultSet结果集执行的所有结果进行分页,是逻辑分页。pageHelper分页插件的基本原理是使用MyBatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截等待执行的sql,然后重写sql,根据结果,添加对应的物理分页参数limit x y。

6.MyBatis一对一、一对多处理

一对一(多对一)

使用association嵌套查询(association使用一个复杂类型的关联将许多结果集包装成一种类型)

<select id="getAllStudent" resultMap="students">
    select * from student
</select>
<resultMap id="students" type="com.study.pojo.Student">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>
    <association property="teacher" javaType="com.study.pojo.Teacher" column="tid" select="teachers" ></association>
</resultMap>
<select id="teachers" resultType="com.study.pojo.Teacher">
    select * from teacher where id=#{id}
</select>
<!--其中association的column是传递的参数,就是给嵌套的子查询传递参数。
也可以使用column="{prop1=col1,prop2=col2}"传递多个参数-->

使用association结果嵌套

<select id="getAllStudent2" resultMap="student2">
    select s.id id,s.name name ,t.id tid,t.name tname from student s,teacher t where s.tid = t.id
</select>

<resultMap id="student2" type="com.study.pojo.Student">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>
    <association property="teacher" javaType="com.study.pojo.Teacher" resultMap="teacher" />
</resultMap>

<resultMap id="teacher" type="com.study.pojo.Teacher">
    <result column="tid" property="id"/>
    <result column="tname" property="name"/>
</resultMap>

一对多

使用collection嵌套查询(一个复杂类型的集合)

<select id="getTeacherStudent" resultMap="teacher1">
    select * from teacher
</select>

<resultMap id="teacher1" type="com.study.pojo.Teacher">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="students" column="id" ofType="com.study.pojo.Student" select="students"/>
</resultMap>

<select id="students" resultType="com.study.pojo.Student">
    select * from student where tid=#{id}
</select>

在这里插入图片描述

使用collection处理结果集

<select id="getTeacherStudent2" resultMap="teacher2">
    select t.id id,t.name name,s.id sid,s.name sname,s.tid tid  from teacher t,student s where t.id=s.tid
</select>

<resultMap id="teacher2" type="com.study.pojo.Teacher">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="students" ofType="com.study.pojo.Student">
        <result column="sid" property="id"/>
        <result column="sname" property="name"/>
        <result column="tid" property="tid"/>
    </collection>
</resultMap>

在这里插入图片描述

7.MyBatis延迟加载

MyBatis默认关闭延迟加载,可以在Mybatis配置文件中配置是否启用延迟加载lazyLoadingEnabled=true|false。
原理是通过代理工具(CGLIB3.5.10已弃用|JAVASSIST)代理目标对象的,当调用方法时,进入拦截器,就会通过拦截器控制invoke方法的执行,实现association或者collection的嵌套查询值处理。

8.MyBatis缓存机制

一级缓存
Mybatis默认开启一级缓存。在一次sql数据库会话中,执行了多次查询条件完全相同的sql,MyBatis提供了一种一级缓存的方案优化,如果是相同的sql语句,会优先名字一级缓存,避免直接对数据库的查询,提高性能。
每个SqlSession中有意Executor引用指向CachingExecutor对象,该对象中有一个Executor引用指向SimpleExecutor对象,在SimpleExecutor对象中有一个引用指向PerpetualCache localCache,这个对象中有属性id固定为LocalCache,还有一个cache名的HashMap集合,map集合的key为方法的一些信息,value为方法查到的结果。

Mybatis一级缓存和生命周期和SqlSession一致。
MyBatis一级缓存设计简单,缓存的集合是一个new HashMap<Object,Object>集合,其中key为sql查询的信息,value为查询出来的结果。
MyBatis的一级缓存存在SqlSession下的CachingExecutor下SimpleExecutor下PerpetualCache中的cacheHashMap集合。

在这里插入图片描述

二级缓存

二级缓存需要手动开启和配置,他是基于 cache 标签所在的映射文件中的语句(基于namespace级别的缓存)。要使用二级缓存,被缓存的对象要实现序列化接口。

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

查看Mybatis源码得知:每次查询都需要通过CachingExecutor先查看二级缓存是否开启,如果没有开启再去查一级缓存有没有数据,最终才连数据库查询。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值