mybatis plus VS 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

Mybatis原理
整体设计:接口层 =》 数据处理层 =》 框架支撑层 =》 引导层

代码层面分析:

执行过程通过动态代理实现
服务启动时候获取SqlSession。

首先,SqlSessionFactoryBuilder去读取mybatis的配置文件,然后build一个DefaultSqlSessionFactory。源码如下:

/**
  * 一系列的构造方法最终都会调用本方法(配置文件为Reader时会调用本方法,还有一个InputStream方法与此对应)
  * @param reader
  * @param environment
  * @param properties
  * @return
  */
 public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
   try {
     //通过XMLConfigBuilder解析配置文件,解析的配置相关信息都会封装为一个Configuration对象
     XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
     //这儿创建DefaultSessionFactory对象
     return build(parser.parse());
   } catch (Exception e) {
     throw ExceptionFactory.wrapException("Error building SqlSession.", e);
   } finally {
     ErrorContext.instance().reset();
     try {
       reader.close();
     } catch (IOException e) {
       // Intentionally ignore. Prefer previous error.
     }
   }
 }

 public SqlSessionFactory build(Configuration config) {
   return new DefaultSqlSessionFactory(config);
 }

当我们获取到SqlSessionFactory之后,就可以通过SqlSessionFactory去获取SqlSession对象。源码如下:

/**
  * 通常一系列openSession方法最终都会调用本方法
  * @param execType 
  * @param level
  * @param autoCommit
  * @return
  */
 private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
   Transaction tx = null;
   try {
     //通过Confuguration对象去获取Mybatis相关配置信息, Environment对象包含了数据源和事务的配置
     final Environment environment = configuration.getEnvironment();
     final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
     tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
     //之前说了,从表面上来看,咱们是用sqlSession在执行sql语句, 实际呢,其实是通过excutor执行, excutor是对于Statement的封装
     final Executor executor = configuration.newExecutor(tx, execType);
     //关键看这儿,创建了一个DefaultSqlSession对象
     return new DefaultSqlSession(configuration, executor, autoCommit);
   } catch (Exception e) {
     closeTransaction(tx); // may have fetched a connection so lets call close()
     throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
   } finally {
     ErrorContext.instance().reset();
   }
 }

通过以上步骤,咱们已经得到SqlSession对象了。接下来就是该干嘛干嘛去了(话说还能干嘛,当然是执行sql语句咯)。看了上面,咱们也回想一下之前写的Demo:

SqlSessionFactory sessionFactory = null;  
String resource = "mybatis-conf.xml";  
try {
    //SqlSessionFactoryBuilder读取配置文件
   sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
} catch (IOException e) {  
   e.printStackTrace();  
}    
//通过SqlSessionFactory获取SqlSession
SqlSession sqlSession = sessionFactory.openSession();

我们可以看到实际创建SqlSession的地方是openSessionFromDataSource,如下:

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {  
 
    Connection connection = null;  
 
    try {  
 
        final Environment environment = configuration.getEnvironment();  
 
        final DataSource dataSource = getDataSourceFromEnvironment(environment);  
        
        // MyBatis对事务的处理相对简单,TransactionIsolationLevel中定义了几种隔离级别,并不支持内嵌事务这样较复杂的场景,同时由于其是持久层的缘故,所以真正在应用开发中会委托Spring来处理事务实现真正的与开发者隔离。分析事务的实现是个入口,借此可以了解不少JDBC规范方面的事情。
        TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);  
 
        connection = dataSource.getConnection();  
 
        if (level != null) {  
            connection.setTransactionIsolation(level.getLevel());
        }  
 
        connection = wrapConnection(connection);  
 
        Transaction tx = transactionFactory.newTransaction(connection,autoCommit);  
 
        Executorexecutor = configuration.newExecutor(tx, execType);  
 
        return newDefaultSqlSession(configuration, executor, autoCommit);  
 
    } catch (Exceptione) {  
        closeConnection(connection);  
        throwExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);  
    } finally {
        ErrorContext.instance().reset();
    }
}

可以看出,创建sqlsession经过了以下几个主要步骤:从配置中获取Environment;从Environment中取得DataSource;从Environment中取得TransactionFactory;从DataSource里获取数据库连接对象Connection;在取得的数据库连接上创建事务对象Transaction;创建Executor对象(该对象非常重要,事实上sqlsession的所有操作都是通过它完成的);创建sqlsession对象。SqlSession咱们也拿到了,咱们可以调用SqlSession中一系列的select..., insert..., update..., delete...方法轻松自如的进行CRUD操作了。就这样?那咱配置的映射文件去哪儿了?别急,咱们接着往下看。
利器之MapperProxy

在mybatis中,通过MapperProxy动态代理咱们的dao, 也就是说, 当咱们执行自己写的dao里面的方法的时候,其实是对应的mapperProxy在代理。那么,咱们就看看怎么获取MapperProxy对象吧:通过SqlSession从Configuration中获取。

JDK动态代理获取mapper实例

posted @   倔强的老铁  阅读(125)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2021-09-15 接收平台消息,模板模式实践
点击右上角即可分享
微信分享提示