001/* 002 * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.mybatis; 017 018import com.mybatisflex.core.audit.AuditManager; 019import org.apache.ibatis.cursor.Cursor; 020import org.apache.ibatis.executor.Executor; 021import org.apache.ibatis.executor.ExecutorException; 022import org.apache.ibatis.executor.parameter.ParameterHandler; 023import org.apache.ibatis.executor.statement.CallableStatementHandler; 024import org.apache.ibatis.executor.statement.SimpleStatementHandler; 025import org.apache.ibatis.executor.statement.StatementHandler; 026import org.apache.ibatis.mapping.BoundSql; 027import org.apache.ibatis.mapping.MappedStatement; 028import org.apache.ibatis.session.Configuration; 029import org.apache.ibatis.session.ResultHandler; 030import org.apache.ibatis.session.RowBounds; 031 032import java.sql.Connection; 033import java.sql.SQLException; 034import java.sql.Statement; 035import java.util.List; 036 037/** 038 * 参考 {@link org.apache.ibatis.executor.statement.RoutingStatementHandler} 039 * 主要作用: 040 * 1、替换 PreparedStatementHandler 为 FlexPreparedStatementHandler 041 * 2、进行数据审计 042 */ 043public class FlexStatementHandler implements StatementHandler { 044 045 private final StatementHandler delegate; 046 private final BoundSql boundSql; 047 private final boolean auditEnable = AuditManager.isAuditEnable(); 048 private final Configuration configuration; 049 private final String stmtId; 050 051 public FlexStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 052 configuration = ms.getConfiguration(); 053 stmtId = ms.getId(); 054 switch (ms.getStatementType()) { 055 case STATEMENT: 056 delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 057 break; 058 case PREPARED: 059 // use FlexPreparedStatementHandler to replace PreparedStatementHandler 060 delegate = new FlexPreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 061 break; 062 case CALLABLE: 063 delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 064 break; 065 default: 066 throw new ExecutorException("Unknown statement type: " + ms.getStatementType()); 067 } 068 069 this.boundSql = delegate.getBoundSql(); 070 } 071 072 @Override 073 public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException { 074 return delegate.prepare(connection, transactionTimeout); 075 } 076 077 @Override 078 public void parameterize(Statement statement) throws SQLException { 079 delegate.parameterize(statement); 080 } 081 082 @Override 083 public void batch(Statement statement) throws SQLException { 084 if (auditEnable) { 085 AuditManager.startAudit(() -> { 086 delegate.batch(statement); 087 return null; 088 }, stmtId, statement, boundSql, configuration); 089 } else { 090 delegate.batch(statement); 091 } 092 } 093 094 @Override 095 public int update(Statement statement) throws SQLException { 096 return auditEnable ? AuditManager.startAudit(() -> delegate.update(statement), stmtId, statement, boundSql, configuration) 097 : delegate.update(statement); 098 } 099 100 @Override 101 public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { 102 return auditEnable ? AuditManager.startAudit(() -> delegate.query(statement, resultHandler), stmtId, statement, boundSql, configuration) 103 : delegate.query(statement, resultHandler); 104 } 105 106 @Override 107 public <E> Cursor<E> queryCursor(Statement statement) throws SQLException { 108 return auditEnable ? AuditManager.startAudit(() -> delegate.queryCursor(statement), stmtId, statement, boundSql, configuration) 109 : delegate.queryCursor(statement); 110 } 111 112 @Override 113 public BoundSql getBoundSql() { 114 return delegate.getBoundSql(); 115 } 116 117 @Override 118 public ParameterHandler getParameterHandler() { 119 return delegate.getParameterHandler(); 120 } 121 122}