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.ResultHandler; 029import org.apache.ibatis.session.RowBounds; 030 031import java.sql.Connection; 032import java.sql.SQLException; 033import java.sql.Statement; 034import java.util.List; 035 036/** 037 * 参考 {@link org.apache.ibatis.executor.statement.RoutingStatementHandler} 038 * 主要作用: 039 * 1、替换 PreparedStatementHandler 为 FlexPreparedStatementHandler 040 * 2、进行数据审计 041 */ 042public class FlexStatementHandler implements StatementHandler { 043 044 private final StatementHandler delegate; 045 private final BoundSql boundSql; 046 private final boolean auditEnable = AuditManager.isAuditEnable(); 047 048 public FlexStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 049 050 switch (ms.getStatementType()) { 051 case STATEMENT: 052 delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 053 break; 054 case PREPARED: 055 // delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 056 // use FlexPreparedStatementHandler to replace PreparedStatementHandler 057 delegate = new FlexPreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 058 break; 059 case CALLABLE: 060 delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); 061 break; 062 default: 063 throw new ExecutorException("Unknown statement type: " + ms.getStatementType()); 064 } 065 066 this.boundSql = delegate.getBoundSql(); 067 } 068 069 @Override 070 public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException { 071 return delegate.prepare(connection, transactionTimeout); 072 } 073 074 @Override 075 public void parameterize(Statement statement) throws SQLException { 076 delegate.parameterize(statement); 077 } 078 079 @Override 080 public void batch(Statement statement) throws SQLException { 081 if (auditEnable) { 082 AuditManager.startAudit(() -> { 083 delegate.batch(statement); 084 return null; 085 }, boundSql); 086 } else { 087 delegate.batch(statement); 088 } 089 } 090 091 @Override 092 public int update(Statement statement) throws SQLException { 093 return auditEnable ? AuditManager.startAudit(() -> delegate.update(statement), boundSql) 094 : delegate.update(statement); 095 } 096 097 @Override 098 public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { 099 return auditEnable ? AuditManager.startAudit(() -> delegate.query(statement, resultHandler), boundSql) 100 : delegate.query(statement, resultHandler); 101 } 102 103 @Override 104 public <E> Cursor<E> queryCursor(Statement statement) throws SQLException { 105 return auditEnable ? AuditManager.startAudit(() -> delegate.queryCursor(statement), boundSql) 106 : delegate.queryCursor(statement); 107 } 108 109 @Override 110 public BoundSql getBoundSql() { 111 return delegate.getBoundSql(); 112 } 113 114 @Override 115 public ParameterHandler getParameterHandler() { 116 return delegate.getParameterHandler(); 117 } 118 119}