001/* 002 * Copyright (c) 2022-2023, 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 050 public FlexStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 051 configuration = ms.getConfiguration(); 052 switch (ms.getStatementType()) { 053 case STATEMENT: 054 delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 055 break; 056 case PREPARED: 057 // use FlexPreparedStatementHandler to replace PreparedStatementHandler 058 delegate = new FlexPreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 059 break; 060 case CALLABLE: 061 delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 062 break; 063 default: 064 throw new ExecutorException("Unknown statement type: " + ms.getStatementType()); 065 } 066 067 this.boundSql = delegate.getBoundSql(); 068 } 069 070 @Override 071 public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException { 072 return delegate.prepare(connection, transactionTimeout); 073 } 074 075 @Override 076 public void parameterize(Statement statement) throws SQLException { 077 delegate.parameterize(statement); 078 } 079 080 @Override 081 public void batch(Statement statement) throws SQLException { 082 if (auditEnable) { 083 AuditManager.startAudit(() -> { 084 delegate.batch(statement); 085 return null; 086 }, statement, boundSql, configuration); 087 } else { 088 delegate.batch(statement); 089 } 090 } 091 092 @Override 093 public int update(Statement statement) throws SQLException { 094 return auditEnable ? AuditManager.startAudit(() -> delegate.update(statement), statement, boundSql, configuration) 095 : delegate.update(statement); 096 } 097 098 @Override 099 public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { 100 return auditEnable ? AuditManager.startAudit(() -> delegate.query(statement, resultHandler), statement, boundSql, configuration) 101 : delegate.query(statement, resultHandler); 102 } 103 104 @Override 105 public <E> Cursor<E> queryCursor(Statement statement) throws SQLException { 106 return auditEnable ? AuditManager.startAudit(() -> delegate.queryCursor(statement), statement, boundSql, configuration) 107 : delegate.queryCursor(statement); 108 } 109 110 @Override 111 public BoundSql getBoundSql() { 112 return delegate.getBoundSql(); 113 } 114 115 @Override 116 public ParameterHandler getParameterHandler() { 117 return delegate.getParameterHandler(); 118 } 119 120}