MyBatis核心知识总结及底层原理应用分析

MyBatis核心知识及底层原理分析

知识整理,持续更新中… …
更多Java学习资源尽在B站账号:
https://space.bilibili.com/591988762
欢迎个位小伙伴前来观看,更多优质学习资源持续更新中…
内容如有差错,欢迎留言一起讨论!!!

本文是对MyBatis核心知识进行的总结,适合有一定基础的小伙伴观看。

一、框架的概念

框架,就是软件的半成品,完成了软件开发过程中的通用操作,程序员只需很少或者不用进行加工就能够实现特定的功能,从而简化开发人员在软件开发中的步骤,提高开发效率。

二、Mybatis介绍

Mybatis是一个半自动ORM框架。

ORM(Object Relational Mapping)对象关系映射,将Java中的一个对象与数据表中一行记录一一对应。

ORM框架提供了实体类与数据表的映射关系,通过映射文件的配置,实现对象的持久化。ORM面向对象程序设计语言和关系型数据库发展不同步时的解决方案,采用 ORM框架后,应用程序不再直接访问底层数据库,而是以面向对象的方式来操作持久化对象,而ORM框架则将这些面向对象的操作转换成底层的 SQL 操作。

通俗的说,ORM框架就是让程序与数据库脱离,通过操作实体进而间接操作数据库。

半自动化框架: 在原生的Java操作基础上进行封装,以简化开发而生,就MyBatis而言,对原生JDBC进行了进一步封装,对开发者而言只需要进行简单的配置就能实现很多功能,之所以说是半自动的,是因为Mybatis尽管做了很多优化封装,我们只需配置调用即可,但是对于SQL来说我们仍然需要自己进行编写,因此是半自动化的。

自动化框架: 对原生操作进行全封装,就Hibernate而言,不需要手动编写SQL,是动态生成的,只需要操作相应的对象即可,大大降低数据库与对象的耦合。可移植性Hibernate比MyBatis高。

优点:

  1. 与JDBC相比,减少了大量的代码量。
  2. 是最简单的持久层框架,简单易学。
  3. SQL代码从程序代码中彻底分离出来,可以重用。
  4. 提供XML标签,支持动态SQL。
  5. 提供映射标签,支持对象与数据库的ORM字段关系映射。
  6. 支持缓存、连接池、数据库移植… .

缺点:

  1. SQL语句编写工作量大,熟练度要高。
  2. 数据库移植性比较差,如果需要切换数据库的话,SQL语句会有很大的差异。

三、MyBatis使用中的细节

3.1 事务提交

在完成MyBatis初始化配置之后,及使用默认配置进行使用的时候,sqlSession默认不是自动提交事务。因此除查询操作外要手动提交事务。
在这里插入图片描述
在这里插入图片描述
如果要自动提交事务,那么在获取SqlSession的时候就要设置自动提交事务。
在这里插入图片描述

3.2 MyBatis创建对象的过程
  1. mybatis-config.xml 配置文件中配置数据库连接信息以及对应的mapper文件。
  2. 将mybatis-config.xnl 配置文件加载成输入流对象。
  3. 得到流对象后传给工厂建造者对象创建MyBatis的会话工厂。
  4. 通过会话工厂创建mybatis与数据库之间的会话对象。
  5. 通过会话对象调用getMapper方法获取对应的对象。
    在这里插入图片描述
3.3 MyBatis条件参数细节

只有一个参数的情况:

  • 如果操作方法只有一个简单类型或者字符串类型的参数,在Mapper配置中可以直接通过#{str}直接获取。
  • 如果操作方法有一个对象类型的参数,在Mapper配置文件中可以直接通过#{attrName}获取指定对象的属性值(attrName必须是参数对象的属性)。
  • 如果操作方法有一个Map类型的参数,在Mapper配置中可以直接通过#{key}获取key对应的value值。

多参数情况:

  • 如果有多个参数,可以采用一下方式获取值:
    • 使用#{agr0},#{agr1}… … 挨个取参数的值
    • 使用#{parm1},#{parm2}… … 挨个取参数的值
    • 给参数加上@Param(“别名”) 使用#{别名} 的方式获取指定参数的值
3.4 Mapper初始化

在这里插入图片描述

四、动态SQL

在多条件查询中,如果查询条件不确定,可以直接使用HashMap作为参数
优点: 无需单独定义传递查询条件的类
缺点: 当向Map中存放参数时,key必须与动态sql保持一致()
public List<Member> searchMember(HashMap<String,Object> params);

mybatis在取值的时候就是通过key来进行映射的。
也可以定义专门用于存放查询条件的实体类存放参数
优点: 设置参数时无需关注属性名
缺点: 需要单独定义一个类来封装参数
public List<Member> searchMember(MemberSearchCondition params);

4.1 where标签和trim标签的区别

where格式:

where如果判定的第一个条件成立,会自动去掉第一个条件的and

<where>
    <if test="gender != null">  <!--gender 就是参数对象的属性/参数Map的key-->
        and member_gender=#{gender}
    </if>
    <if test="minAge != null">
        and member_age &gt;= #{minAge}   <!-- &gt; -->
    </if>
    <if test="maxAge != null">
        and member_age &lt;= #{maxAge}  <!-- &lt; -->
    </if>
    <if test="city != null">
        and member_city = #{city}
    </if>
</where>

trim格式:

trim可以实现和where一样的效果,但是功能比where更强大。

trim可以自动添加前缀、后缀等。

prefix=“where”: 如果有条件成立就添加上前缀

prefixOverrides=“and | or”: 在条件成立的情况下,如果第一个语句有and或者or,直接去掉。

suffix=“order by member_age”: 添加后缀,比如这种条件。

<trim prefix="where" prefixOverrides="and | or" suffix="order by member_age">
    <if test="gender != null">  <!--gender 就是参数对象的属性/参数Map的key-->
        and member_gender=#{gender}
    </if>
    <if test="minAge != null">
        and member_age &gt;= #{minAge}   <!-- &gt; -->
    </if>
    <if test="maxAge != null">
        and member_age &lt;= #{maxAge}  <!-- &lt; -->
    </if>
    <if test="city != null">
        and member_city = #{city}
    </if>
</trim>

foreach标签:

foreach标签用户遍历有多个参数的,一般都封装在集合中的。

collection=“list”: 指定的是集合的类型,使用的是别名。

item=“cityName”: 集合遍历出来的每一项。

separator=“,”: 每一项之间用什么拼接

open=“(” close=“)”: 多个项之间的开闭规则

<foreach collection="list" item="cityName" separator="," open="(" close=")">
    #{cityName}
</foreach>

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

注意:模糊查询使用${}取值,与sql进行拼接时,即使只有一个参数也需要使用@Param注解声明参数的key(非String对象参数可以不用声明)

${}:表示获取参数,是先获取参数的值,然后拼接到SQL语句上,再进行编译,不能解决SQL注入问题。

#{}:也是获取参数,但是是先完成SQL的预编译处理,在预编译之后,再将获取的值设置到SQL中。可以防止SQL注入问题。使用#{}做模糊查询,只需要在外面拼接好字符串就可以了。

#{}是预编译处理,是占位符,${}是字符串替换、是拼接符。

六、 日志信息的级别

在使用日志框架输出日志信息的时候,会根据输出的日志信息的重要程度分为5个级别

级别说明
DEBUG输出调试信息
INFO输出提示信息
WARN输出警告信息
ERROR一般性错误信息
FATAL致命性错误信息

七、MyBatis缓存

MyBatis是基于JDBC的封装,使数据库操作更加便捷;MyBatis除了对JDBC操作步骤进行封装之外也对其性能进行了优化:

  • 在MyBatis引入缓存机制,用于提升MyBatis的检索效率
  • 在MyBatis引入延迟加载机制,用于减少对数据库不必要的访问
7.1 一级缓存

一级缓存也叫做SqlSession级缓存,为每个SqlSession单独分配的缓存内存,无需手动开启可直接使用;多个SqlSession的缓存是不共享的。

特性:

1.如果多次查询使用的是同一个SqlSession对象,则第一次查询之后数据会存放到缓存,后续的查询则直接访问缓存中存储的数据;

2.如果第一次查询完成之后,对查询出的对象进行修改(此修改会影响到缓存),第二次查询会直接访问缓存,造成第二次查询的结果与数据库不一致;

实际上查询出来的对象是存在缓存中的,我们进行修改,修改的就是缓存中的引用。
在这里插入图片描述
3.当我们进行在查询时想要跳过缓存直接查询数据库,则可以通过sqlSession.clearCache();来清除当前SqlSession的缓存;

4.如果第一次查询之后第二查询之前,使用当前的sqlsession执行了修改操作,此修改操作会使第一次查询并缓存的数据失效,因此第二次查询会再次访问数据库。

7.2 一级缓存在应用中存在的问题

以在Servlet中使用MyBatis为例,两个servlet一个做查询,一个做修改,两个使用的是不同的SqlSession,查询的servlet第一次查询出数据之后,就存入缓存,后面就不会访问数据库,即使修改的Servlet修改之后,二者不是同一个SqlSession,也不会改变。要解决的办法,可以使用单例模式创建一个对象或者每次操作完就清空缓存。

在这里插入图片描述

7.3 二级缓存

二级缓存也称为SqlSessionFactory级缓存,通过同一个factory对象获取的Sqlsession可以共享二级缓存;在应用服务器中SqlSessionFactory是单例的,因此我们二级缓存可以实现全局共享。

特性:

1.二级缓存默认没有开启,需要在mybatis-config.xml中的settings标签开启

2.二级缓存只能缓存实现序列化接口的对象

  • 在mybatis-config.xml开启使用二级缓存

    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
  • 在需要使用二级缓存的Mapper文件中配置cache标签使用功能二级缓存

    <cache/>
    
  • 被缓存的实体类实现序列化接口

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class Member implements Serializable {
        private int memberId;
        private String memberNick;
        private String memberGender;
        private int memberAge;
        private String memberCity;
    }
    

总结: 二级缓存是SqlSessionFactory级的缓存,只要使用的同一个SqlSessionFactory创建的SqlSession,查询的数据都能放到缓存中,要注意的是二级缓存默认没有开启,需要我们手动开启二级缓存,并且在需要实现二级缓存的类上实现序列化。

还有要注意的就是,二级缓存,我们在做查询的时候,不管有没有开启事务提交,都需要手动提交事务才能存入二级缓存中。
在这里插入图片描述
注意:二级缓存默认没有清除缓存的功能的,但是我们可以在操作SQL的时候控制使不使用缓存。
在这里插入图片描述

7.4 MyBatis的延迟加载

mybatis的延迟加载针对的是子查询,所谓延迟加载,就是在存在子查询的情况下,在执行了子查询(至少查询两次及以上)时,默认只执行第一次查询,当用到子查询时,才会触发子查询执行,如果无需使用子查询的结果,那么就不会执行子查询。
在这里插入图片描述

以上是MyBatis基础核心内容的总结,接下来是MyBatis框架底层原理及应用的分析,内容在更新中,敬请期待!!!

MyBatis框架底层分析

一、代理模式在MyBatis框架中的使用

二、工厂模式在MyBatis框架中的使用

三、Builder(建造者)模式在MyBatis框架中的使用

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值