MyBatis基础(三) 底层调用JDBC--源码分析

本文深入探讨MyBatis如何通过SqlSession接口调用executor执行CRUD操作,重点分析executor.update和executor.query方法。executor接口封装了StatementHandler,而Executor的实现类ExecutorWrapper和SimpleExecutor涉及到了查询缓存和JDBC语句的执行。RowBounds用于处理查询结果的分页,ResultHandler则负责结果的映射。BoundSql包含了动态SQL和参数信息。
摘要由CSDN通过智能技术生成

系列内容回顾:

前面的文章分析了Mybatis是如何在给定接口的情况下, 代替我们生成代理对象的, 这篇文章接着带大家来学习Mybatis.

在之前提到, 无论是用代理生成Dao类还是自己手写Dao类, 都是用工厂方法获得一个SqlSession, 然后调用其select, update, insert方法; 我们也知道, 如果用最原始的JDBC的方法来写, 通常落到执行层面, 通常就是pstmt.executeUpdate, pstmt.executeQuery, pstmt.execute, stmt.execute这样的一些方法. 那么Mybatis中是如何代替我们用SqlSession的方法去操纵底层JDBC的, 这就是今天想分析的内容.

SqlSession

SqlSession是Mybatis中非常重要的接口, 通过定义了对数据库的常见操作的方法, 屏蔽了底层jdbc细节, 我们先看下该接口提供的方法都有哪些.
在这里插入图片描述

可以看到, 除了commit, rollback这样的事务相关的方法, 大多数方法支持的是各种模式的CRUD. 我们可以将他们分为两个部分, 一个是select相关的, 一个是update相关的(update/delete/insert), 通过阅读源码可以发现后者中的方法最终都是对update(String statement, Object parameter)这样一个方法进行的封装; 而前者中提供的各种方法是对

  • select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)
  • selectCursor(String statement, Object parameter, RowBounds rowBounds)
  • selectList(String statement, Object parameter, RowBounds rowBounds)

进行的封装. 因此接下来的重点就是上述的四个方法.

executor.update

update(String statement, Object parameter)方法的底层调用的是executor.update(MappedStatement ms, Object parameter)方法, executor 则是SqlSession中执行数据库操作的实际对象, 通过跟踪代码, 可以看到, executor是个一个接口, 里面封装了query和update两种sql statement的执行模型, 这个接口有的接口大致如下:
在这里插入图片描述
在SqlSession中, 实际实际引入的executor的实现类是CachingExecutor, 但是注意到CachingExecutor本身是一个装饰器模式, 用来处理和查询缓存相关的工作, 其真正功能由成员Executor delegate完成, delegate是一个SimpleExecutor的实例, 这个类的结构很简单

/**
 * @author Clinton Begin
 */
public class SimpleExecutor extends BaseExecutor {
   
  public SimpleExecutor(Configuration configuration, Transaction transaction) {
   
  }
  @Override
  public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
   
  }
  @Override
  public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException 
MyBatis-Plus并没有直接集成Neo4j JDBC驱动,但是可以通过MyBatis-Plus提供的自定义SQL执行器来使用Neo4j JDBC驱动。 首先需要在项目中引入Neo4j JDBC驱动的依赖,可以在Maven中添加以下依赖: ```xml <dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-jdbc-driver</artifactId> <version>4.3.1</version> </dependency> ``` 然后在MyBatis-Plus的配置类中配置自定义SQL执行器,示例如下: ```java @Configuration public class MybatisPlusConfig { @Bean public ConfigurationCustomizer configurationCustomizer() { return configuration -> { // 添加自定义SQL执行器 configuration.addInterceptor(new MyNeo4jJdbcInterceptor()); }; } /** * 自定义SQL执行器,使用Neo4j JDBC驱动执行SQL */ private static class MyNeo4jJdbcInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 获取MappedStatement和参数 MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; Object parameter = invocation.getArgs()[1]; // 获取SQL语句 BoundSql boundSql = mappedStatement.getBoundSql(parameter); String sql = boundSql.getSql(); // 使用Neo4j JDBC驱动执行SQL try (Connection connection = DriverManager.getConnection("jdbc:neo4j:bolt://localhost:7687", "neo4j", "password"); PreparedStatement statement = connection.prepareStatement(sql)) { // 设置参数 ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameter, boundSql); parameterHandler.setParameters(statement); // 执行SQL if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) { statement.execute(); } else { throw new RuntimeException("Unsupported result set type: " + mappedStatement.getResultSetType()); } // 返回结果 ResultSet resultSet = statement.getResultSet(); return new MyResultSet(resultSet); } } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { // do nothing } } /** * 自定义ResultSet,用于包装Neo4j JDBC驱动返回的ResultSet */ private static class MyResultSet implements ResultSet { private final ResultSet resultSet; public MyResultSet(ResultSet resultSet) { this.resultSet = resultSet; } // 实现ResultSet接口的方法,用于包装Neo4j JDBC驱动返回的ResultSet // ... } } ``` 以上代码中,`MyNeo4jJdbcInterceptor`是自定义的SQL执行器,使用Neo4j JDBC驱动执行SQL。在`intercept`方法中,获取SQL语句和参数,使用Neo4j JDBC驱动执行SQL,并将返回的`ResultSet`包装为`MyResultSet`返回。 需要注意的是,自定义SQL执行器需要添加到MyBatis-Plus的配置中,这里使用了`ConfigurationCustomizer`实现。同时,由于Neo4j JDBC驱动返回的`ResultSet`和MyBatis-Plus默认的`ResultSet`不同,需要自定义`MyResultSet`实现`ResultSet`接口,用于包装Neo4j JDBC驱动返回的`ResultSet`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值