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

com.github.chengyuxing.sql.utils.JdbcUtil Maven / Gradle / Ivy

package com.github.chengyuxing.sql.utils;

import com.github.chengyuxing.common.DataRow;
import com.github.chengyuxing.common.MostDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Date;
import java.sql.*;
import java.time.*;
import java.util.*;

/**
 * JDBC util.
 */
public class JdbcUtil {
    private static final Logger log = LoggerFactory.getLogger(JdbcUtil.class);

    public static Object getResultValue(ResultSet resultSet, int index) throws SQLException {
        Object obj = resultSet.getObject(index);
        String className = null;
        if (Objects.nonNull(obj)) {
            className = obj.getClass().getName();
        }
        if (obj instanceof Blob) {
            obj = getBytes((Blob) obj);
        } else if (obj instanceof Clob clob) {
            obj = clob.getSubString(1, (int) clob.length());
        } else if ("org.postgresql.jdbc.PgArray".equals(className)) {
            obj = resultSet.getArray(index).getArray();
        } else if ("org.postgresql.util.PGobject".equals(className)) {
            obj = resultSet.getString(index);
        } else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) {
            obj = resultSet.getTimestamp(index);
        } else if (className != null && className.startsWith("oracle.sql.DATE")) {
            String metaDataClassName = resultSet.getMetaData().getColumnClassName(index);
            if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) {
                obj = resultSet.getTimestamp(index);
            } else {
                obj = resultSet.getDate(index);
            }
        } else if (obj instanceof java.sql.Date) {
            if ("java.sql.Timestamp".equals(resultSet.getMetaData().getColumnClassName(index))) {
                obj = resultSet.getTimestamp(index);
            }
        }
        return obj;
    }

    public static void setStatementValue(PreparedStatement ps, int index, Object value) throws SQLException {
        if (Objects.isNull(value)) {
            ps.setNull(index, Types.NULL);
        } else if (value instanceof java.util.Date date) {
            ps.setObject(index, new Timestamp(date.getTime()));
        } else if (value instanceof LocalDateTime localDateTime) {
            ps.setObject(index, new Timestamp(localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
        } else if (value instanceof LocalDate localDate) {
            ps.setObject(index, new Date(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()));
        } else if (value instanceof LocalTime localTime) {
            ps.setObject(index, new Time(localTime.atDate(LocalDate.now()).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()));
        } else if (value instanceof OffsetDateTime offsetDateTime) {
            ps.setObject(index, new Timestamp(offsetDateTime.toInstant().toEpochMilli()));
        } else if (value instanceof OffsetTime offsetTime) {
            ps.setObject(index, new Time(offsetTime.atDate(LocalDate.now()).toInstant().toEpochMilli()));
        } else if (value instanceof ZonedDateTime zonedDateTime) {
            ps.setObject(index, new Timestamp(zonedDateTime.toInstant().toEpochMilli()));
        } else if (value instanceof Instant instant) {
            ps.setObject(index, new Timestamp(instant.toEpochMilli()));
        } else if (value instanceof MostDateTime mostDateTime) {
            ps.setObject(index, new Timestamp(mostDateTime.toInstant().toEpochMilli()));
        } else if (value instanceof UUID) {
            ps.setObject(index, value.toString().replace("-", ""));
        } else if (value instanceof InputStream inputStream) {
            ps.setBinaryStream(index, inputStream);
        } else if (value instanceof Path path) {
            try {
                ps.setBinaryStream(index, Files.newInputStream(path));
            } catch (IOException e) {
                throw new SQLException("set binary value failed.", e);
            }
        } else if (value instanceof File file) {
            try {
                ps.setBinaryStream(index, new FileInputStream(file));
            } catch (FileNotFoundException e) {
                throw new SQLException("set binary value failed.", e);
            }
        } else {
            ps.setObject(index, value);
        }
    }

    public static byte[] getBytes(Blob blob) throws SQLException {
        byte[] bytes = new byte[0];
        if (Objects.nonNull(blob)) {
            try (InputStream ins = blob.getBinaryStream()) {
                bytes = new byte[(int) blob.length()];
                //noinspection ResultOfMethodCallIgnored
                ins.read(bytes);
            } catch (IOException e) {
                throw new UncheckedIOException("read blob catch an error.", e);
            }
        }
        return bytes;
    }

    /**
     * Do execute query, ddl, dml or plsql statement to get result.
* Get result by index {@code 0} or by name: {@code result} . * * @param statement preparedStatement * @param sql executed sql * @return DataRow * @throws SQLException sql exp */ public static DataRow getResult(PreparedStatement statement, final String sql) throws SQLException { var resultSet = statement.getResultSet(); if (Objects.nonNull(resultSet)) { var result = JdbcUtil.createDataRows(resultSet, sql, -1); JdbcUtil.closeResultSet(resultSet); return DataRow.of("result", result, "type", "QUERY"); } int i = statement.getUpdateCount(); if (i != -1) { return DataRow.of("result", i, "type", "DD(M)L"); } return new DataRow(0); } /** * Print sql log, e.g. postgresql: *
     * raise notice 'my console.';
*
* * @param sc sql statement object */ public static void printSqlConsole(Statement sc) { if (log.isWarnEnabled()) { try { var warning = sc.getWarnings(); if (warning != null) { var state = warning.getSQLState(); warning.forEach(r -> log.warn("[{}] [{}] {}", LocalDateTime.now(), state, r.getMessage())); } } catch (SQLException e) { log.error("get sql warning error.", e); } } } public static void closeResultSet(ResultSet resultSet) throws SQLException { if (Objects.nonNull(resultSet)) { if (!resultSet.isClosed()) { resultSet.close(); } } } public static void closeStatement(Statement statement) throws SQLException { if (Objects.nonNull(statement)) { if (!statement.isClosed()) { statement.close(); } } } /** * Create fields array by query resulSet. * * @param resultSet query resulSet * @param executedSql executed query sql, check column which be double-quoted for exclude case-sensitive column * @return fields array * @throws SQLException ex */ public static String[] createNames(ResultSet resultSet, final String executedSql) throws SQLException { var metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); String[] names = new String[columnCount]; for (int i = 0; i < columnCount; i++) { String columnName = metaData.getColumnName(i + 1); if (!executedSql.contains("\"" + columnName + "\"")) { columnName = columnName.toLowerCase(); } if (columnName.equals("?column?")) { columnName = "column" + i; } names[i] = columnName; } return names; } /** * Create DataRow from resultSet. * * @param names fields array * @param resultSet resultSet * @return DataRow * @throws SQLException ex */ public static DataRow createDataRow(String[] names, ResultSet resultSet) throws SQLException { var row = new DataRow(names.length); for (int i = 0; i < names.length; i++) { row.put(names[i], getResultValue(resultSet, i + 1)); } return row; } /** * Create DataRows from resultSet. * * @param resultSet resultSet * @param executedSql executed query sql, check column which be double-quoted for exclude case-sensitive column * @param fetchSize request result set size * @return DataRows * @throws SQLException ex */ public static List createDataRows(final ResultSet resultSet, final String executedSql, final long fetchSize) throws SQLException { if (Objects.isNull(resultSet)) { return Collections.emptyList(); } List list = new ArrayList<>(); String[] names = createNames(resultSet, executedSql); long size = fetchSize; while (resultSet.next()) { if (size == 0) break; list.add(createDataRow(names, resultSet)); size--; } return list; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy