orm框架之mybaits/mybaits_plus

链接: mybatis中文文档
在这里插入图片描述

       //第一步获取文件
       String resource = "org/mybatis/example/mybatis-config.xml";
        Reader reader = null;
        try {
        //第二步,读取文件io信息
            reader = Resources
                    .getResourceAsReader(resource);
        } catch (IOException e) {

        }
        //SqlSessionFactory 工厂,里面就是读取config文件里面的信息
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(reader);
        SqlSession sqlSession = build.openSession();
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        Blog blog = mapper.selectBlog(101);

SqlSessionFactory 中的XMLConfigBuilder解析配置文件,XMLConfigBuilder只能使用一次,因为Configuration是全局的,
XMLConfigBuilder 解析xml配置文件
Configuration就是存入的配置的文件,bean文件

1.0 mapper与接口绑定原理分析

通过jdk动态代理模式来实现的—重要代码之一:MapperProxy—ProxyClassFactory生成的代理类会调用invoke,因此可以证明MyBatis是使用JDK动态代理实现的。

public class MapperProxy<T> implements InvocationHandler, Serializable {
    private static final long serialVersionUID = -6424540398559729838L;
    private static final int ALLOWED_MODES = 15;
    private static final Constructor<Lookup> lookupConstructor;
    private static final Method privateLookupInMethod;
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethod> methodCache;

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
        this.methodCache = methodCache;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
         //判断是否Object的方法,如toString、hashCode直接调用 ,调用里面的方法
            if(Object.class.equals(method.getDeclaringClass())) {
                return method.invoke(this, args);
            }

            if(method.isDefault()) {
                if(privateLookupInMethod == null) {
                    return this.invokeDefaultMethodJava8(proxy, method, args);
                }

                return this.invokeDefaultMethodJava9(proxy, method, args);
            }
        } catch (Throwable var5) {
            throw ExceptionUtil.unwrapThrowable(var5);
        }
     //通过method获取构造时传入的MapperMethod
        MapperMethod mapperMethod = this.cachedMapperMethod(method);
         //执行方法代码
        return mapperMethod.execute(this.sqlSession, args);
    }
    

2.0 mybaits sqlsession 一级缓存

链接: 美团聊聊mybaits 缓存机制.
在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能
在这里插入图片描述

一级缓存,会有概率出现脏数据,当同一个SqlSession 执行时,会出现第二次,走的是一级缓存,如果是分布式缓存,第二次查询数据对不上。
每个SqlSession中持有了Executor,每个Executor中有一个LocalCache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。新增。修改,删除时,就会清楚缓存
在这里插入图片描述

spring 融合mybaits—里面有个final,写了个清除缓存的方法
如果没有开启事务,每一次sql都是用的新的SqlSession,这时mybatis的一级缓存是失效的。
如果有事务,同一个事务中相同的查询使用的相同的SqlSessioon,此时一级缓存是生效的。

一级缓存总结:缓存用的是hashMap,缓存key:方法类+id+sql语句作为key
MyBatis一级缓存的生命周期和SqlSession一致。
MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。

3.0 mybaits sqlsession 二级缓存

二级缓存使用了很多装饰设计模式,自己整合redis,encha就行,默认是开启本地缓存encha

4.0 mybaits 生命周期

1:SqlSessionFactoryBuilder(构造器)
2:SqlSessionFactory(工厂接口)
3:Sqlsession(会话)
4:SQL Mapper(映射器)

SqlSessionFactoryBuilder : SqlSessionFactoryBuilder的作用在于创建SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用,所以它只能存在于创建SqlSessionFactory的方法中,而不要让其长期存在。

SqlSessionFactory : 可以被认为是一个数据库连接池, 它的作用是创建Session接口对象。因为MyBatis的本质就是Java对数据库的操作,所以SqlSessionFactory的生命周期存在于整个MyBatis的应用之中,所以一旦创建 了SqlSessionFactory,就要长期保存它,直至不再使用MyBatis应用,所以可以认为SqlSessionFactory的生命周期就等同于MyBatis的应用周期。由于SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源,如果创建多个SqlSessionFactory, 那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。因此在一般的应用中我们往往希望SqlSessionFactory作为一个单例(Singleton), 让它在应用中被共享。

如果说SlssonFactory相当于数据库连接池,那么SqlSession就相当于一个数据库连接(Conection对象),你可以在一个事务里面执行多条SQL,然后通过它的commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给SqlSessionFactory, 否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用try{}catch{} fnally{}语句来保证其正确关闭。

Mapper是个接口, 它由Ssesion所创建,所以它的最大生命周期至多和SqlSession一致,随着SqlSession的关闭,它的数据库连接资源也会消失,所以。Mapper生命周期\leqslantSqlSession生命周期。Mapper是一个请求中的业务处理,所以它应该在一个请求中, 当相关业务处理完毕后就应该销毁它。

5.0 mybaits 常用设计模式

1:Builder模式:

例如SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder;
:2:工厂模式:

例如SqlSessionFactory、ObjectFactory、MapperProxyFactory;
:3:单例模式:例如ErrorContext和LogFactory;
:4:代理模式:Mybatis实现的核心,比如MapperProxy、ConnectionLogger,用的jdk的动态代理;还有executor.loader包使用了cglib或者javassist达到延迟加载的效果;
:5:组合模式:例如SqlNode和各个子类ChooseSqlNode等;
:6:模板方法模式: 例如BaseExecutor和SimpleExecutor,还有BaseTypeHandler和所有的子类例如IntegerTypeHandler;
:7:适配器模式: 例如Log的Mybatis接口和它对jdbc、log4j等各种日志框架的适配实现;
:8:装饰者模式: 例如cache包中的cache.decorators子包中等各个装饰者的实现;
:9:迭代器模式: 例如迭代器模式PropertyTokenizer;

6.0 mybaits 一些问题

1:A系统给B系统一条SQL是正确SQL—通过语法引擎,而mybaits 里面的xml,需要通过语法引擎检测,然后改写sql,执行sql语句—后面很多分库分表shardJdbc,阿里seata 也是重写sql语句

2:mybaits 是一个半ORM(对象关系映射),mybaits 可以使用xml或注解来配置和映射原生信息,将POJO映射成数据库中的记录,也可以通过手写SQL语句

3:#{}和 , {}, {}是字符串替换,#{} 是预处理—可以有效的防止SQL注入,提高系统安全性

6.0 mybaits_plus

官网链接:https://baomidou.com/guide/
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

  • 特性
  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

组件:实现逻辑删除,全局id/自定义全局id,自定义分页插件,代码生成器,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值