• MyBatis学习篇


    什么是MyBatis

    (1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。
    (2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
    (3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。

    MyBatis的优点和缺点

    优点:
    (1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
    (2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
    (3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
    (4)能够与Spring很好的集成;
    (5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
    缺点
    (1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
    (2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

    MyBatis-Plus 优点 MyBatis-Plus为简化开发而生

    Mybatis-Plus是一个Mybatis的增强工具,只是在Mybatis的基础上做了增强却不做改变,MyBatis-Plus支持所有Mybatis原生的特性,所以引入Mybatis-Plus不会对现有的Mybatis构架产生任何影响。
    1、依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring 。
    2、损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 。
    3、预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击 。
    4、通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 。
    5、多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题 。
    6、支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
    7、支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
    8、支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码(生成自定义文件,避免开发重复代码),支持模板引擎、有超多自定义配置等。
    9、支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )。
    10、支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词 。
    11、内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。
    12、内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询 。
    13、内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作。
    14、默认将实体类的类名查找数据库中的表,使用@TableName(value="table1")注解指定表名,@TableId指定表主键,若字段与表中字段名保持一致可不加注解。

    #{}和${}的区别是什么?

    #{}是预编译处理,${}是字符串替换。
    Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
    Mybatis在处理${}时,就是把${}替换成变量的值。
    使用#{}可以有效的防止SQL注入,提高系统安全性。

    Mybatis的传值方式

    • 单个传值
    • 顺序传值
    • 对象传值
    • Map传值
    • 列表传值

    Mybatis中的标签

    【cache】:给定命名空间的缓存配置。
    【cache-ref】:引用其他命名空间的缓存配置。
    【resultMap】:描述如何从数据库结果集中来加载对象。
    【sql】:定制SQL片段。id为唯一标识,使用“引入sql片段。”
    【insert】:映射插入语句。
    【update】:映射更新语句。
    【delete】:映射删除语句。
    【select】:映射查询语句。
    【动态sql,主要由if、where、foreach、set等动态标签组成】

    Mybatis是如何进行分页的?分页插件的原理是什么?

    • Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。
    • 可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
    • 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

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

    第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。
    第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
    有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

    Mybatis的一级、二级、自定义缓存:

    Mybatis缓存可以大大提升系统的性能,Mybatis提供一级缓存和二级缓存。

    MyBatis的缓存分为一级缓存和二级缓存,两种缓存的缓存粒度是一样的,都是对应一条sql查询语句,但是二者的生命周期是不一样的。
    一级缓存的生命周期是SqlSession对象的使用期间,随着SqlSession对象的死亡而消失;
    二级缓存的生命周期是同MyBatis应用一样长。
    一级缓存

    • MyBatis 默认开启了一级缓存,一级缓存是在SqlSession 层面进行缓存的。
    • 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空。
    • 即同一个SqlSession ,多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,以后直接先从缓存中取出数据,不会直接去查数据库。
    • 但是不同的SqlSession对象,因为不用的SqlSession都是相互隔离的,所以相同的Mapper、参数和方法,他还是会再次发送到SQL到数据库去执行,返回结果。
    • 一级缓存失效
      1. sqlSession不同
      2. 当sqlSession对象相同的时候,查询的条件不同,原因是第一次查询时候一级缓存中没有第二次查询所需要的数据
      3. 当sqlSession对象相同,两次查询之间进行了插入的操作
      4. 当sqlSession对象相同,手动清除了一级缓存中的数据

    二级缓存

    • 二级缓存与一级缓存其机制相同,默认二级缓存是不开启的,需要手动进行配置。
    • 不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如:encache和redis。
    • 为了克服一级缓存失效的问题,需要开启二级缓存,缓存在SqlSessionFactory层面给各个SqlSession 对象共享。
    • 一级缓存可能存在脏读情况,默认的二级缓存毕竟也是存储在本地缓存,所以对于微服务下是可能出现脏读的情况的,所以这时候我们可能会需要自定义缓存,比如利用redis来存储缓存,而不是存储在本地内存当中。

    自定义缓存

    • MyBatis官方也提供了一些第三方缓存的支持,如:encache和redis。
    • 如果要实现一个自己的缓存的话,那么我们只需要新建一个类实现Cache接口就好了。

    缓存数据更新机制:当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。

  • 相关阅读:
    转 webpack 插件 svg-sprite-loader
    form-data与x-www-form-urlencoded的区别【转】
    nginx echo 高级语法 echo_location【转】
    占位【转】
    gocron在linux环境下安装及设置开机启动【转】
    AES加密2【转】
    Redis的KEYS命令引起宕机事件【纯转】
    Java四种锁及分布式锁的初解【纯转】
    java转发二进制图片流【原】
    SpringBoot整合Redis及Redis工具类撰写【纯转】
  • 原文地址:https://www.cnblogs.com/zhaojinhui/p/16266687.html
Copyright © 2020-2023  润新知