All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hundsun.lightdb.unisql.proxy.jdbc.UnisqlPreparedStatement Maven / Gradle / Ivy

There is a newer version: 24.1.7.0-beta-2
Show newest version
package com.hundsun.lightdb.unisql.proxy.jdbc;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hundsun.lightdb.unisql.golang.PreparedParameter;
import com.hundsun.lightdb.unisql.golang.Transformer;
import com.hundsun.lightdb.unisql.golang.VariableParameter;
import com.hundsun.lightdb.unisql.model.UnisqlProperties;
import com.hundsun.lightdb.unisql.utils.MicroServiceParameterUtils;
import com.hundsun.lightdb.unisql.utils.Utils;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLType;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhuxd
 * @date 2023/1/30
 */
@Slf4j
public class UnisqlPreparedStatement extends UnisqlStatement implements PreparedStatement {

    private final UnisqlConnection connection;
    private final PreparedStatement delegate;
    /**
     * 预编译SQL
     */
    private final String comparePreparedSql;
    /**
     * 存储的是comparePreparedBindingVariables按照下标顺序排序后的每一批绑定变量
     */
    protected final List> comparePreparedBindingVariablesBatch;
    /**
     * 每一批的绑定变量,按照下标作为key
     */
    protected final ConcurrentHashMap comparePreparedBindingVariables;


    public UnisqlPreparedStatement(UnisqlConnection connection, PreparedStatement delegate, String comparePreparedSql) {
        super(connection, delegate);
        this.connection = connection;
        this.delegate = delegate;
        this.comparePreparedSql = comparePreparedSql;
        this.comparePreparedBindingVariablesBatch = new ArrayList<>();
        this.comparePreparedBindingVariables = new ConcurrentHashMap<>();
    }

    public PreparedStatement getDelegate() {
        return delegate;
    }

    @Override
    public ResultSet executeQuery() throws SQLException {
        isCompare(false);
        return new UnisqlResultSet(delegate.executeQuery());
    }


    /**
     * 预编译是否调用比对服务(go内部使用),因为java这边预编译sql调用转换获取不到绑定变量值,比对服务开启时,预编译的SQL会调用两次;第一次预编译sql时,此参数为1
     * 不调用比对服务,第二次获取到绑定变量值后,此参数为0 调用比对服务。
     *
     * @param: isBatch 是否批量
     * @return: void
     * @Author: liangdong30629
     * @Date: 2024/6/12 11:38
     */
    private void isCompare(boolean isBatch) {
        // sql http发到比对中心服务
        if (Transformer.IS_COMPARE) {

            try {
                VariableParameter variableParameter = VariableParameter.builder()
                        .dbName(connection.getDataBase())
                        .build();
                if (isBatch) {
                    if (comparePreparedBindingVariablesBatch.size() > 0) {

                        ObjectMapper jsonMapper = new ObjectMapper();
                        String globalJson = jsonMapper.writeValueAsString(comparePreparedBindingVariablesBatch);
                        variableParameter.setSqlParameters(globalJson);

                    }
                } else {
                    ArrayList x = getSortObjectArrayList();
                    if (x.size() > 0) {
                        List> list = new ArrayList<>();
                        list.add(x);

                        ObjectMapper jsonMapper = new ObjectMapper();
                        String globalJson = jsonMapper.writeValueAsString(list);
                        variableParameter.setSqlParameters(globalJson);
                    }
                }
                // 采集微服务参数开关打开
                if (UnisqlProperties.collectMicroServiceParametersEnabled) {
                    // 采集微服务参数
                    MicroServiceParameterUtils.collectMicroServiceParameters(variableParameter);
                }

                Transformer.parse(comparePreparedSql, connection.getSourceDialect().name(),
                        connection.getTargetDialect().name(), variableParameter);
            } catch (JsonProcessingException e) {
                if (log.isErrorEnabled()) {
                    log.error("Comparison call exception !", e);
                }
            }
        }
    }

    @Override
    public int executeUpdate() throws SQLException {
        isCompare(false);
        return delegate.executeUpdate();
    }

    @Override
    public void setNull(int parameterIndex, int sqlType) throws SQLException {
        delegate.setNull(parameterIndex, sqlType);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setNull")
                    .parameterIndex(parameterIndex)
                    .x(null)
                    .vendorTypeNumber(sqlType)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
        delegate.setBoolean(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setBoolean")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setByte(int parameterIndex, byte x) throws SQLException {
        delegate.setByte(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setByte")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setShort(int parameterIndex, short x) throws SQLException {
        delegate.setShort(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setShort")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setInt(int parameterIndex, int x) throws SQLException {
        delegate.setInt(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setInt")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setLong(int parameterIndex, long x) throws SQLException {
        delegate.setLong(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setLong")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setFloat(int parameterIndex, float x) throws SQLException {
        delegate.setFloat(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setFloat")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setDouble(int parameterIndex, double x) throws SQLException {
        delegate.setDouble(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setDouble")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
        delegate.setBigDecimal(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setBigDecimal")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setString(int parameterIndex, String x) throws SQLException {
        delegate.setString(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setString")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
        delegate.setBytes(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setBytes")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setDate(int parameterIndex, Date x) throws SQLException {
        delegate.setDate(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setDate")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setTime(int parameterIndex, Time x) throws SQLException {
        delegate.setTime(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setTime")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
        delegate.setTimestamp(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setTimestamp")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setAsciiStream(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setAsciiStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting ASCII stream length", e);
            }
        } else {
            delegate.setAsciiStream(parameterIndex, x, length);
        }
    }

    @Override
    @Deprecated
    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setUnicodeStream(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setUnicodeStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Unicode stream length", e);
            }
        } else {
            delegate.setUnicodeStream(parameterIndex, x, length);
        }
    }

    @Override
    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setBinaryStream(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setBinaryStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Binary stream length", e);
            }
        } else {
            delegate.setBinaryStream(parameterIndex, x, length);
        }
    }

    @Override
    public void clearParameters() throws SQLException {
        try {
            delegate.clearParameters();
        } finally {
            if (Transformer.IS_COMPARE) {
                comparePreparedBindingVariables.clear();
            }
        }

    }

    @Override
    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
        delegate.setObject(parameterIndex, x, targetSqlType);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setObject")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .vendorTypeNumber(targetSqlType)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setObject(int parameterIndex, Object x) throws SQLException {
        delegate.setObject(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setObject")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public boolean execute() throws SQLException {
        isCompare(false);
        return delegate.execute();
    }

    @Override
    public void addBatch() throws SQLException {
        delegate.addBatch();
        if (Transformer.IS_COMPARE) {
            comparePreparedBindingVariablesBatch.add(getSortObjectArrayList());
            comparePreparedBindingVariables.clear();
        }
    }


    @Override
    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setCharacterStream(parameterIndex, bufferedReader1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setCharacterStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setCharacterStream Reader length. Underlying cause: " + e.getMessage(),
                        e);
            }
        } else {
            delegate.setCharacterStream(parameterIndex, reader, length);
        }
    }

    @Override
    public void setRef(int parameterIndex, Ref x) throws SQLException {
        delegate.setRef(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setRef")
                    .parameterIndex(parameterIndex)
                    .x(x.getBaseTypeName())
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

        }
    }

    @Override
    public void setBlob(int parameterIndex, Blob x) throws SQLException {
        delegate.setBlob(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            try {
                // 转成base64传输
                PreparedParameter preparedParameter = PreparedParameter.builder()
                        .methodName("setBlob")
                        .parameterIndex(parameterIndex)
                        .x(Utils.byteArrayOutputStreamToBase64(Utils.blobToByteArrayOutputStream(x)))
                        .base64Flag(true)
                        .build();
                comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting setBlob. Underlying cause: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public void setClob(int parameterIndex, Clob x) throws SQLException {
        delegate.setClob(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            try {
                // 转成base64传输
                PreparedParameter preparedParameter = PreparedParameter.builder()
                        .methodName("setClob")
                        .parameterIndex(parameterIndex)
                        .x(Utils.byteArrayOutputStreamToBase64(Utils.clobToByteArrayOutputStream(x)))
                        .base64Flag(true)
                        .build();
                comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
            } catch (IOException e) {
                throw new SQLException("Error setting setClob. Underlying cause: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public void setArray(int parameterIndex, Array x) throws SQLException {
        delegate.setArray(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                 ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);) {
                objectOutputStream.writeObject(x.getArray());
                // 将 ARRAY 值转换为字节数组
                byte[] byteArray = byteArrayOutputStream.toByteArray();
                // 转成base64传输
                PreparedParameter preparedParameter = PreparedParameter.builder()
                        .methodName("setArray")
                        .parameterIndex(parameterIndex)
                        .x(Base64.getEncoder().encodeToString(byteArray))
                        .base64Flag(true)
                        .build();
                comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
            } catch (Exception e) {
                throw new SQLException("Error setting setArray. Underlying cause: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public ResultSetMetaData getMetaData() throws SQLException {
        return delegate.getMetaData();
    }

    @Override
    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
        delegate.setDate(parameterIndex, x, cal);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setDate")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .calendar(cal)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
        delegate.setTime(parameterIndex, x, cal);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setTime")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .calendar(cal)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
        delegate.setTimestamp(parameterIndex, x, cal);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setTimestamp")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .calendar(cal)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
        delegate.setNull(parameterIndex, sqlType, typeName);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setNull")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(null)
                    .vendorTypeNumber(sqlType)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setURL(int parameterIndex, URL x) throws SQLException {
        delegate.setURL(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setURL")
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public ParameterMetaData getParameterMetaData() throws SQLException {
        return delegate.getParameterMetaData();
    }

    @Override
    public void setRowId(int parameterIndex, RowId x) throws SQLException {
        delegate.setRowId(parameterIndex, x);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setRowId")
                    .parameterIndex(parameterIndex)
                    .x(x.toString())
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setNString(int parameterIndex, String value) throws SQLException {
        delegate.setNString(parameterIndex, value);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setNString")
                    .parameterIndex(parameterIndex)
                    .x(value)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(value);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setNCharacterStream(parameterIndex, bufferedReader1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setNCharacterStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting NCharacter Reader length. Underlying cause: " + e.getMessage(),
                        e);
            }
        } else {
            delegate.setNCharacterStream(parameterIndex, value, length);
        }
    }

    @Override
    public void setNClob(int parameterIndex, NClob value) throws SQLException {
        delegate.setNClob(parameterIndex, value);
        if (Transformer.IS_COMPARE) {
            try {
                // 转成base64传输
                PreparedParameter preparedParameter = PreparedParameter.builder()
                        .methodName("setNClob")
                        .parameterIndex(parameterIndex)
                        .x(Utils.clobToByteArrayOutputStream(value))
                        .base64Flag(true)
                        .build();
                comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
            } catch (IOException e) {
                throw new SQLException("Error setting setNClob. Underlying cause: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setClob(parameterIndex, bufferedReader1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setClob")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Clob Reader length. Underlying cause: " + e.getMessage(),
                        e);
            }
        } else {
            delegate.setClob(parameterIndex, reader, length);
        }
    }

    @Override
    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(inputStream, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setBlob(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setBlob")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Blob stream length", e);
            }
        } else {
            delegate.setBlob(parameterIndex, inputStream, length);
        }
    }

    @Override
    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setNClob(parameterIndex, bufferedReader1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setNClob")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting NClob Reader length. Underlying cause: " + e.getMessage(),
                        e);
            }
        } else {
            delegate.setNClob(parameterIndex, reader, length);
        }
    }

    @Override
    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
        delegate.setSQLXML(parameterIndex, xmlObject);
        if (Transformer.IS_COMPARE) {
            try {
                // Use reflection to call getString method on SQLXML object
                Method getStringMethod = xmlObject.getClass().getDeclaredMethod("getStringVal");
                getStringMethod.setAccessible(true);
                String xmlString = (String) getStringMethod.invoke(xmlObject);
                PreparedParameter preparedParameter = PreparedParameter.builder()
                        .methodName("setSQLXML")
                        .parameterIndex(parameterIndex)
                        .x(xmlString)
                        .build();
                comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
            } catch (Exception e) {
                throw new SQLException("Error setting setSQLXML. Underlying cause: " + e.getMessage(), e);
            }
        }
    }

    @Override
    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
        delegate.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setObject")
                    .parameterCount(4)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .vendorTypeNumber(targetSqlType)
                    .scaleOrLength(scaleOrLength)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setAsciiStream(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setAsciiStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Ascii stream length", e);
            }
        } else {
            delegate.setAsciiStream(parameterIndex, x, length);
        }
    }

    @Override
    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setBinaryStream(parameterIndex, inputStream1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setBinaryStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Binary stream length", e);
            }
        } else {
            delegate.setBinaryStream(parameterIndex, x, length);
        }
    }

    @Override
    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setCharacterStream(parameterIndex, bufferedReader1, length);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setCharacterStream")
                            .parameterCount(3)
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .scaleOrLength(length)
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Character Reader length. Underlying cause: " + e.getMessage(),
                        e);
            }
        } else {
            delegate.setCharacterStream(parameterIndex, reader, length);
        }
    }

    @Override
    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setAsciiStream(parameterIndex, inputStream1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setAsciiStream")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting ASCII stream", e);
            }
        } else {
            delegate.setAsciiStream(parameterIndex, x);
        }
    }

    @Override
    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(x, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setBinaryStream(parameterIndex, inputStream1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setBinaryStream")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Binary stream", e);
            }
        } else {
            delegate.setBinaryStream(parameterIndex, x);
        }
    }

    @Override
    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setCharacterStream(parameterIndex, bufferedReader1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setCharacterStream")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting CharacterStream Reader. Underlying cause: " + e.getMessage(), e);
            }

        } else {
            delegate.setCharacterStream(parameterIndex, reader);
        }
    }

    @Override
    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(value);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setNCharacterStream(parameterIndex, bufferedReader1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setNCharacterStream")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting NCharacterStream Reader. Underlying cause: " + e.getMessage(), e);
            }

        } else {
            delegate.setNCharacterStream(parameterIndex, value);
        }
    }

    @Override
    public void setClob(int parameterIndex, Reader reader) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setClob(parameterIndex, bufferedReader1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setClob")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Clob Reader. Underlying cause: " + e.getMessage(), e);
            }

        } else {
            delegate.setClob(parameterIndex, reader);
        }
    }

    @Override
    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
                // 优化读取流的逻辑为一个独立方法
                copyInputStreamToByteArray(inputStream, byteArrayOutputStream);

                try (// 从缓存的数据中读取数据,创建 ByteArrayInputStream 对象
                     InputStream inputStream1 = new ByteArrayInputStream(byteArrayOutputStream.toByteArray())) {

                    delegate.setBlob(parameterIndex, inputStream1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setBlob")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }
            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting Blob stream", e);
            }
        } else {
            delegate.setBlob(parameterIndex, inputStream);
        }
    }

    @Override
    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
        if (Transformer.IS_COMPARE) {
            try {
                // 优化Reader逻辑为一个独立方法
                ByteArrayOutputStream byteArrayOutputStream = copyReaderToByteArrayOutputStream(reader);
                // 从缓存的数据中读取数据,创建 BufferedReader 对象
                try (Reader bufferedReader1 =
                             new InputStreamReader(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()))) {

                    delegate.setNClob(parameterIndex, bufferedReader1);
                    // 转成base64传输
                    PreparedParameter preparedParameter = PreparedParameter.builder()
                            .methodName("setNClob")
                            .parameterIndex(parameterIndex)
                            .x(Utils.byteArrayOutputStreamToBase64(byteArrayOutputStream))
                            .base64Flag(true)
                            .build();
                    comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
                }

            } catch (IOException e) {
                // 优化异常处理
                throw new SQLException("Error setting NClob Reader. Underlying cause: " + e.getMessage(), e);
            }
        } else {
            delegate.setNClob(parameterIndex, reader);
        }
    }

    @Override
    public void setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException {
        delegate.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setObject")
                    .parameterCount(4)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .targetSqlType(targetSqlType)
                    .scaleOrLength(scaleOrLength)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);

        }
    }

    @Override
    public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throws SQLException {
        delegate.setObject(parameterIndex, x, targetSqlType);
        if (Transformer.IS_COMPARE) {
            PreparedParameter preparedParameter = PreparedParameter.builder()
                    .methodName("setObject")
                    .parameterCount(3)
                    .parameterIndex(parameterIndex)
                    .x(x)
                    .targetSqlType(targetSqlType)
                    .build();
            comparePreparedBindingVariables.put(parameterIndex, preparedParameter);
        }
    }

    @Override
    public long executeLargeUpdate() throws SQLException {
        isCompare(false);
        return delegate.executeLargeUpdate();
    }

    @Override
    public int[] executeBatch() throws SQLException {
        isCompare(true);
        return super.executeBatch();
    }

    @Override
    public void clearBatch() throws SQLException {
        try {
            super.clearBatch();
        } finally {
            if (Transformer.IS_COMPARE) {
                comparePreparedBindingVariablesBatch.clear();
            }
        }

    }

    /**
     * 获取升序排序后的 ArrayList
     *
     * @return ArrayList
     */
    private ArrayList getSortObjectArrayList() {
        // 将 Map 的键值对按照键的顺序排序
        List> entryList =
                new ArrayList<>(comparePreparedBindingVariables.entrySet());
        Collections.sort(entryList, Comparator.comparingInt(ConcurrentHashMap.Entry::getKey));

        // 创建 ArrayList 对象存储排序后的值
        ArrayList x = new ArrayList();
        for (ConcurrentHashMap.Entry entry : entryList) {
            x.add(entry.getValue());
        }
        return x;
    }

    /**
     * 读取输入流数据到 缓冲区中
     *
     * @param input  输入流
     * @param output 输出流
     * @throws IOException 如果读取或写入过程中发生 I/O 错误
     */
    private void copyInputStreamToByteArray(InputStream input, ByteArrayOutputStream output) throws IOException {
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

    /**
     * 读取字符流数据到缓冲区
     *
     * @param value Reader输入
     * @return ByteArrayOutputStream 缓存对象
     * @throws IOException 如果读取或写入过程中发生 I/O 错误
     */
    private ByteArrayOutputStream copyReaderToByteArrayOutputStream(Reader value) throws IOException {
        try (
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                Writer writer = new OutputStreamWriter(byteArrayOutputStream)) {

            char[] buffer = new char[1024];
            int bytesRead;
            while ((bytesRead = value.read(buffer)) != -1) {
                writer.write(buffer, 0, bytesRead);
            }
            writer.flush();
            return byteArrayOutputStream;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy