mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
fix code
This commit is contained in:
parent
e33f9c82eb
commit
430c63b9bc
@ -66,7 +66,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
this.dbConfig = ((DSWrapper) ds).getDbConfig();
|
||||
this.caseInsensitive = this.dbConfig.isCaseInsensitive();
|
||||
}
|
||||
this.runner = new DialectRunner(dialect);
|
||||
this.runner = new DialectRunner(this.dbConfig, dialect);
|
||||
}
|
||||
// ------------------------------------------------------- Constructor end
|
||||
|
||||
@ -134,7 +134,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public Number queryNumber(final String sql, final Object... params) throws DbException {
|
||||
return query(sql, new NumberHandler(), params);
|
||||
return query(sql, NumberHandler.INSTANCE, params);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +163,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.query(conn, sql, rsh, params);
|
||||
return SqlExecutor.of(this.dbConfig, conn).query(sql, rsh, params);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -184,7 +184,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.query(conn, sql, rsh, paramMap);
|
||||
return SqlExecutor.of(this.dbConfig, conn).query(sql, rsh, paramMap);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -205,7 +205,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.query(conn, statementFunc, rsh);
|
||||
return SqlExecutor.of(this.dbConfig, conn).query(statementFunc, rsh);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -227,7 +227,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.execute(conn, sql, params);
|
||||
return SqlExecutor.of(this.dbConfig, conn).execute(sql, params);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -246,7 +246,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.executeForGeneratedKey(conn, sql, params);
|
||||
return SqlExecutor.of(this.dbConfig, conn).executeForGeneratedKey(sql, params);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -265,7 +265,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.executeBatch(conn, sql, paramsBatch);
|
||||
return SqlExecutor.of(this.dbConfig, conn).executeBatch(sql, paramsBatch);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -283,7 +283,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.executeBatch(conn, sqls);
|
||||
return SqlExecutor.of(this.dbConfig, conn).executeBatch(sqls);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
@ -301,7 +301,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = this.getConnection();
|
||||
return SqlExecutor.executeBatch(conn, sqls);
|
||||
return SqlExecutor.of(this.dbConfig, conn).executeBatch(sqls);
|
||||
} finally {
|
||||
this.closeConnection(conn);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
package org.dromara.hutool.db;
|
||||
|
||||
import org.dromara.hutool.core.func.SerConsumer;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.db.dialect.Dialect;
|
||||
import org.dromara.hutool.db.dialect.DialectFactory;
|
||||
import org.dromara.hutool.db.ds.DSUtil;
|
||||
@ -33,6 +34,7 @@ import java.sql.SQLException;
|
||||
public class Db extends AbstractDb<Db> {
|
||||
private static final long serialVersionUID = -3378415769645309514L;
|
||||
|
||||
// region ----- of
|
||||
/**
|
||||
* 创建Db<br>
|
||||
* 使用默认数据源,自动探测数据库连接池
|
||||
@ -62,7 +64,7 @@ public class Db extends AbstractDb<Db> {
|
||||
* @return Db
|
||||
*/
|
||||
public static Db of(final DataSource ds) {
|
||||
return ds == null ? null : new Db(ds);
|
||||
return of(ds, DialectFactory.getDialect(ds));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,37 +77,7 @@ public class Db extends AbstractDb<Db> {
|
||||
public static Db of(final DataSource ds, final Dialect dialect) {
|
||||
return new Db(ds, dialect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建Db
|
||||
*
|
||||
* @param ds 数据源
|
||||
* @param driverClassName 数据库连接驱动类名
|
||||
* @return Db
|
||||
*/
|
||||
public static Db of(final DataSource ds, final String driverClassName) {
|
||||
return new Db(ds, DialectFactory.newDialect(driverClassName));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------- Constructor start
|
||||
/**
|
||||
* 构造,从DataSource中识别方言
|
||||
*
|
||||
* @param ds 数据源
|
||||
*/
|
||||
public Db(final DataSource ds) {
|
||||
this(ds, DialectFactory.getDialect(ds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param ds 数据源
|
||||
* @param driverClassName 数据库连接驱动类名,用于识别方言
|
||||
*/
|
||||
public Db(final DataSource ds, final String driverClassName) {
|
||||
this(ds, DialectFactory.newDialect(driverClassName));
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 构造
|
||||
@ -116,7 +88,6 @@ public class Db extends AbstractDb<Db> {
|
||||
public Db(final DataSource ds, final Dialect dialect) {
|
||||
super(ds, dialect);
|
||||
}
|
||||
// ---------------------------------------------------------------------------- Constructor end
|
||||
|
||||
/**
|
||||
* 执行事务,使用默认的事务级别<br>
|
||||
|
@ -18,12 +18,15 @@ import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.regex.PatternPool;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.Dialect;
|
||||
import org.dromara.hutool.db.dialect.DialectFactory;
|
||||
import org.dromara.hutool.db.handler.NumberHandler;
|
||||
import org.dromara.hutool.db.handler.PageResultHandler;
|
||||
import org.dromara.hutool.db.handler.RsHandler;
|
||||
import org.dromara.hutool.db.sql.*;
|
||||
import org.dromara.hutool.db.sql.Query;
|
||||
import org.dromara.hutool.db.sql.QuoteWrapper;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
import org.dromara.hutool.db.sql.SqlUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
@ -41,30 +44,19 @@ import java.util.regex.Pattern;
|
||||
public class DialectRunner implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Dialect dialect;
|
||||
/**
|
||||
* 是否大小写不敏感(默认大小写不敏感)
|
||||
*/
|
||||
protected boolean caseInsensitive = true;
|
||||
private final DbConfig config;
|
||||
private final Dialect dialect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 数据库配置
|
||||
* @param dialect 方言
|
||||
*/
|
||||
public DialectRunner(final Dialect dialect) {
|
||||
public DialectRunner(final DbConfig config, final Dialect dialect) {
|
||||
this.config = config;
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param driverClassName 驱动类名,用于识别方言
|
||||
*/
|
||||
public DialectRunner(final String driverClassName) {
|
||||
this(DialectFactory.newDialect(driverClassName));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------- CRUD start
|
||||
|
||||
/**
|
||||
@ -114,10 +106,10 @@ public class DialectRunner implements Serializable {
|
||||
* @since 5.7.20
|
||||
*/
|
||||
public int upsert(final Connection conn, final Entity record, final String... keys) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
PreparedStatement ps = this.dialect.psForUpsert(conn, record, keys);
|
||||
try {
|
||||
ps = getDialect().psForUpsert(conn, record, keys);
|
||||
} catch (final SQLException ignore) {
|
||||
ps = this.dialect.psForUpsert(conn, record, keys);
|
||||
} catch (final DbException ignore) {
|
||||
// 方言不支持,使用默认
|
||||
}
|
||||
if (null != ps) {
|
||||
@ -264,11 +256,7 @@ public class DialectRunner implements Serializable {
|
||||
public <T> T find(final Connection conn, final Query query, final RsHandler<T> rsh) throws DbException {
|
||||
checkConn(conn);
|
||||
Assert.notNull(query, "[query] is null !");
|
||||
try {
|
||||
return SqlExecutor.queryAndClosePs(dialect.psForFind(conn, query), rsh);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
return StatementUtil.executeQuery(dialect.psForFind(conn, query), rsh);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,11 +269,7 @@ public class DialectRunner implements Serializable {
|
||||
*/
|
||||
public long count(final Connection conn, final Query query) throws DbException {
|
||||
checkConn(conn);
|
||||
try {
|
||||
return SqlExecutor.queryAndClosePs(dialect.psForCount(conn, query), new NumberHandler()).longValue();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
return StatementUtil.executeQuery(dialect.psForCount(conn, query), NumberHandler.INSTANCE).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -309,13 +293,8 @@ public class DialectRunner implements Serializable {
|
||||
selectSql = matcher.group(1);
|
||||
}
|
||||
|
||||
try {
|
||||
return SqlExecutor.queryAndClosePs(dialect.psForCount(conn,
|
||||
SqlBuilder.of(selectSql).addParams(sqlBuilder.getParamValueArray())),
|
||||
new NumberHandler()).longValue();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
return StatementUtil.executeQuery(dialect.psForCount(conn,
|
||||
SqlBuilder.of(selectSql).addParams(sqlBuilder.getParamValueArray())), NumberHandler.INSTANCE).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -333,7 +312,7 @@ public class DialectRunner implements Serializable {
|
||||
// 分页查询中总数的查询要去掉分页信息
|
||||
new PageResult<>(page, (int) count(conn, query.clone().setPage(null))));
|
||||
|
||||
return page(conn, query, entityResultHandler.setCaseInsensitive(caseInsensitive));
|
||||
return page(conn, query, entityResultHandler.setCaseInsensitive(this.config.isCaseInsensitive()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -353,11 +332,7 @@ public class DialectRunner implements Serializable {
|
||||
return this.find(conn, query, rsh);
|
||||
}
|
||||
|
||||
try {
|
||||
return SqlExecutor.queryAndClosePs(dialect.psForPage(conn, query), rsh);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
return StatementUtil.executeQuery(dialect.psForPage(conn, query), rsh);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,7 +349,7 @@ public class DialectRunner implements Serializable {
|
||||
final PageResultHandler<Entity> entityResultHandler = PageResultHandler.of(
|
||||
new PageResult<>(page, (int) count(conn, sqlBuilder)));
|
||||
|
||||
return page(conn, sqlBuilder, page, entityResultHandler.setCaseInsensitive(caseInsensitive));
|
||||
return page(conn, sqlBuilder, page, entityResultHandler.setCaseInsensitive(this.config.isCaseInsensitive()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,49 +367,10 @@ public class DialectRunner implements Serializable {
|
||||
*/
|
||||
public <T> T page(final Connection conn, final SqlBuilder sqlBuilder, final Page page, final RsHandler<T> rsh) throws DbException {
|
||||
checkConn(conn);
|
||||
if (null == page) {
|
||||
return SqlExecutor.query(conn, sqlBuilder, rsh);
|
||||
}
|
||||
|
||||
final PreparedStatement ps;
|
||||
try {
|
||||
ps = dialect.psForPage(conn, sqlBuilder, page);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
return SqlExecutor.queryAndClosePs(ps, rsh);
|
||||
return StatementUtil.executeQuery(dialect.psForPage(conn, sqlBuilder, page), rsh);
|
||||
}
|
||||
//---------------------------------------------------------------------------- CRUD end
|
||||
|
||||
//---------------------------------------------------------------------------- Getters and Setters start
|
||||
|
||||
/**
|
||||
* 设置是否在结果中忽略大小写<br>
|
||||
* 如果忽略,则在Entity中调用getXXX时,字段值忽略大小写,默认忽略
|
||||
*
|
||||
* @param caseInsensitive 否在结果中忽略大小写
|
||||
* @since 5.2.4
|
||||
*/
|
||||
public void setCaseInsensitive(final boolean caseInsensitive) {
|
||||
this.caseInsensitive = caseInsensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SQL方言
|
||||
*/
|
||||
public Dialect getDialect() {
|
||||
return dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置SQL方言
|
||||
*
|
||||
* @param dialect 方言
|
||||
*/
|
||||
public void setDialect(final Dialect dialect) {
|
||||
this.dialect = dialect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置包装器,包装器用于对表名、字段名进行符号包装(例如双引号),防止关键字与这些表名或字段冲突
|
||||
*
|
||||
@ -452,11 +388,12 @@ public class DialectRunner implements Serializable {
|
||||
public void setWrapper(final QuoteWrapper quoteWrapper) {
|
||||
this.dialect.setWrapper(quoteWrapper);
|
||||
}
|
||||
//---------------------------------------------------------------------------- Getters and Setters end
|
||||
|
||||
//---------------------------------------------------------------------------- Private method start
|
||||
/**
|
||||
* 检查{@link Connection} 可用性
|
||||
* @param conn 数据库连接
|
||||
*/
|
||||
private void checkConn(final Connection conn) {
|
||||
Assert.notNull(conn, "Connection object must be not null!");
|
||||
}
|
||||
//---------------------------------------------------------------------------- Private method start
|
||||
}
|
||||
|
@ -79,16 +79,6 @@ public class Session extends AbstractDb<Session> implements Closeable {
|
||||
this(ds, DialectFactory.getDialect(ds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param ds 数据源
|
||||
* @param driverClassName 数据库连接驱动类名,用于识别方言
|
||||
*/
|
||||
public Session(final DataSource ds, final String driverClassName) {
|
||||
this(ds, DialectFactory.newDialect(driverClassName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
@ -279,21 +269,6 @@ public class Session extends AbstractDb<Session> implements Closeable {
|
||||
|
||||
// ---------------------------------------------------------------------------- Transaction method end
|
||||
|
||||
@Override
|
||||
public void closeConnection(final Connection conn) {
|
||||
try {
|
||||
if(conn != null && false == conn.getAutoCommit()) {
|
||||
// 事务中的Session忽略关闭事件
|
||||
return;
|
||||
}
|
||||
} catch (final SQLException e) {
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
// 普通请求关闭(或归还)连接
|
||||
ThreadLocalConnection.INSTANCE.close(this.ds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closeConnection(null);
|
||||
|
@ -14,7 +14,9 @@ package org.dromara.hutool.db;
|
||||
|
||||
import org.dromara.hutool.core.array.ArrayUtil;
|
||||
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.handler.ResultSetUtil;
|
||||
import org.dromara.hutool.db.handler.RsHandler;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
@ -34,47 +36,22 @@ import java.util.Map;
|
||||
*/
|
||||
public class StatementUtil {
|
||||
|
||||
/**
|
||||
* 创建{@link PreparedStatement}
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param sqlBuilder {@link SqlBuilder}包括SQL语句和参数
|
||||
* @return {@link PreparedStatement}
|
||||
* @since 4.1.3
|
||||
*/
|
||||
public static PreparedStatement prepareStatement(final Connection conn, final SqlBuilder sqlBuilder) {
|
||||
return prepareStatement(conn, sqlBuilder.build(), sqlBuilder.getParamValueArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link PreparedStatement}
|
||||
*
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param params "?"对应参数列表或者Map表示命名参数
|
||||
* @return {@link PreparedStatement}
|
||||
* @since 3.2.3
|
||||
*/
|
||||
public static PreparedStatement prepareStatement(final Connection conn, final String sql, final Object... params) {
|
||||
return prepareStatement(true, conn, sql, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建{@link PreparedStatement}
|
||||
*
|
||||
* @param returnGeneratedKey 当为insert语句时,是否返回主键
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param params "?"对应参数列表或者Map表示命名参数
|
||||
* @param config 数据库配置
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param params "?"对应参数列表或者Map表示命名参数
|
||||
* @return {@link PreparedStatement}
|
||||
* @since 5.8.19
|
||||
*/
|
||||
public static PreparedStatement prepareStatement(final boolean returnGeneratedKey,
|
||||
final Connection conn, final String sql, final Object... params) {
|
||||
public static PreparedStatement prepareStatement(final boolean returnGeneratedKey, final DbConfig config, final Connection conn, final String sql, final Object... params) {
|
||||
return StatementBuilder.of()
|
||||
.setConnection(conn)
|
||||
.setReturnGeneratedKey(returnGeneratedKey)
|
||||
.setSqlFilter(SqlLogFilter.INSTANCE)
|
||||
.setSqlFilter(config.getSqlFilters())
|
||||
.setSql(sql)
|
||||
.setParams(params)
|
||||
.build();
|
||||
@ -83,31 +60,33 @@ public class StatementUtil {
|
||||
/**
|
||||
* 创建批量操作的{@link PreparedStatement}
|
||||
*
|
||||
* @param config 数据库配置
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param paramsBatch "?"对应参数批次列表
|
||||
* @return {@link PreparedStatement}
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public static PreparedStatement prepareStatementForBatch(final Connection conn, final String sql, final Object[]... paramsBatch) {
|
||||
return prepareStatementForBatch(conn, sql, new ArrayIter<>(paramsBatch));
|
||||
public static PreparedStatement prepareStatementForBatch(final DbConfig config, final Connection conn, final String sql, final Object[]... paramsBatch) {
|
||||
return prepareStatementForBatch(config, conn, sql, new ArrayIter<>(paramsBatch));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建批量操作的{@link PreparedStatement}
|
||||
*
|
||||
* @param config 数据库配置
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param paramsBatch "?"对应参数批次列表
|
||||
* @return {@link PreparedStatement}
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public static PreparedStatement prepareStatementForBatch(final Connection conn, final String sql,
|
||||
public static PreparedStatement prepareStatementForBatch(final DbConfig config, final Connection conn, final String sql,
|
||||
final Iterable<Object[]> paramsBatch) {
|
||||
return StatementBuilder.of()
|
||||
.setConnection(conn)
|
||||
.setReturnGeneratedKey(false)
|
||||
.setSqlFilter(SqlLogFilter.INSTANCE)
|
||||
.setSqlFilter(config.getSqlFilters())
|
||||
.setSql(sql)
|
||||
.setParams(ArrayUtil.ofArray(paramsBatch, Object.class))
|
||||
.buildForBatch();
|
||||
@ -116,6 +95,7 @@ public class StatementUtil {
|
||||
/**
|
||||
* 创建{@link CallableStatement}
|
||||
*
|
||||
* @param config 数据库配置
|
||||
* @param conn 数据库连接
|
||||
* @param sql SQL语句,使用"?"做为占位符
|
||||
* @param params "?"对应参数列表
|
||||
@ -123,10 +103,10 @@ public class StatementUtil {
|
||||
* @throws SQLException SQL异常
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public static CallableStatement prepareCall(final Connection conn, final String sql, final Object... params) throws SQLException {
|
||||
public static CallableStatement prepareCall(final DbConfig config, final Connection conn, final String sql, final Object... params) throws SQLException {
|
||||
return StatementBuilder.of()
|
||||
.setConnection(conn)
|
||||
.setSqlFilter(SqlLogFilter.INSTANCE)
|
||||
.setSqlFilter(config.getSqlFilters())
|
||||
.setSql(sql)
|
||||
.setParams(params)
|
||||
.buildForCall();
|
||||
@ -250,4 +230,47 @@ public class StatementUtil {
|
||||
public static void setParam(final PreparedStatement ps, final int paramIndex, final Object param) throws SQLException {
|
||||
StatementWrapper.of(ps).setParam(paramIndex, param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询
|
||||
*
|
||||
* @param ps {@link PreparedStatement}
|
||||
* @param rsh 结果集处理对象
|
||||
* @param <T> 结果类型
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.1.13
|
||||
*/
|
||||
public static <T> T executeQuery(final PreparedStatement ps, final RsHandler<T> rsh) throws DbException {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = ps.executeQuery();
|
||||
return rsh.handle(rs);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(rs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。<br>
|
||||
* INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。<br>
|
||||
* executeUpdate 的返回值是一个整数(int),指示受影响的行数(即更新计数)。<br>
|
||||
* 对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。<br>
|
||||
* 此方法不会关闭PreparedStatement
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param params 参数
|
||||
* @return 影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static int executeUpdate(final PreparedStatement ps, final Object... params) throws DbException {
|
||||
try {
|
||||
StatementUtil.fillArrayParam(ps, params);
|
||||
return ps.executeUpdate();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.db.config;
|
||||
|
||||
import org.dromara.hutool.db.Db;
|
||||
import org.dromara.hutool.db.driver.DriverUtil;
|
||||
import org.dromara.hutool.db.sql.filter.SqlFilter;
|
||||
import org.dromara.hutool.db.sql.filter.SqlFilterChain;
|
||||
@ -280,6 +281,15 @@ public class DbConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SQL过滤器
|
||||
*
|
||||
* @return SQL过滤器
|
||||
*/
|
||||
public SqlFilterChain getSqlFilters(){
|
||||
return this.sqlFilters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加SQL过滤器
|
||||
*
|
||||
|
@ -18,6 +18,9 @@ import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.DbException;
|
||||
import org.dromara.hutool.db.driver.DriverUtil;
|
||||
import org.dromara.hutool.db.sql.SqlLog;
|
||||
import org.dromara.hutool.db.sql.filter.SqlLogFilter;
|
||||
import org.dromara.hutool.log.level.Level;
|
||||
import org.dromara.hutool.setting.Setting;
|
||||
import org.dromara.hutool.setting.props.Props;
|
||||
|
||||
@ -61,16 +64,19 @@ public class SettingConfigParser implements ConfigParser {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DbConfig parse(String group) {
|
||||
if (group == null) {
|
||||
group = StrUtil.EMPTY;
|
||||
}
|
||||
|
||||
final Setting subSetting = setting.getSetting(group);
|
||||
public DbConfig parse(final String group) {
|
||||
final Setting setting = this.setting;
|
||||
final Setting subSetting = setting.getSetting(StrUtil.emptyIfNull(group));
|
||||
if (MapUtil.isEmpty(subSetting)) {
|
||||
throw new DbException("No config for group: [{}]", group);
|
||||
}
|
||||
|
||||
// 继承属性
|
||||
subSetting.putIfAbsent(DSKeys.KEY_SHOW_SQL, setting.get(DSKeys.KEY_SHOW_SQL));
|
||||
subSetting.putIfAbsent(DSKeys.KEY_FORMAT_SQL, setting.get(DSKeys.KEY_FORMAT_SQL));
|
||||
subSetting.putIfAbsent(DSKeys.KEY_SHOW_PARAMS, setting.get(DSKeys.KEY_SHOW_PARAMS));
|
||||
subSetting.putIfAbsent(DSKeys.KEY_SQL_LEVEL, setting.get(DSKeys.KEY_SQL_LEVEL));
|
||||
|
||||
return toDbConfig(subSetting);
|
||||
}
|
||||
|
||||
@ -108,9 +114,7 @@ public class SettingConfigParser implements ConfigParser {
|
||||
throw new DbException("No JDBC URL!");
|
||||
}
|
||||
|
||||
// 移除用户可能误加入的show sql配置项
|
||||
// issue#I3VW0R@Gitee
|
||||
removeShowSqlParams(setting);
|
||||
final SqlLogFilter sqlLogFilter = getSqlLogFilter(setting);
|
||||
|
||||
// 自动识别Driver
|
||||
String driver = setting.getAndRemove(DSKeys.KEY_ALIAS_DRIVER);
|
||||
@ -122,7 +126,8 @@ public class SettingConfigParser implements ConfigParser {
|
||||
.setUrl(url)
|
||||
.setDriver(driver)
|
||||
.setUser(setting.getAndRemove(DSKeys.KEY_ALIAS_USER))
|
||||
.setPass(setting.getAndRemove(DSKeys.KEY_ALIAS_PASSWORD));
|
||||
.setPass(setting.getAndRemove(DSKeys.KEY_ALIAS_PASSWORD))
|
||||
.addSqlFilter(sqlLogFilter);
|
||||
|
||||
// 大小写等配置
|
||||
final String caseInsensitive = setting.getAndRemove(DSKeys.KEY_CASE_INSENSITIVE);
|
||||
@ -164,12 +169,22 @@ public class SettingConfigParser implements ConfigParser {
|
||||
* 此方法用于移除用户配置在分组下的配置项目
|
||||
*
|
||||
* @param setting 配置项
|
||||
* @since 5.7.2
|
||||
* @return {@link SqlLogFilter}
|
||||
*/
|
||||
private static void removeShowSqlParams(final Setting setting) {
|
||||
setting.remove(DSKeys.KEY_SHOW_SQL);
|
||||
setting.remove(DSKeys.KEY_FORMAT_SQL);
|
||||
setting.remove(DSKeys.KEY_SHOW_PARAMS);
|
||||
setting.remove(DSKeys.KEY_SQL_LEVEL);
|
||||
private static SqlLogFilter getSqlLogFilter(final Setting setting) {
|
||||
// 初始化SQL显示
|
||||
final boolean isShowSql = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_SQL), false);
|
||||
final boolean isFormatSql = Convert.toBoolean(setting.remove(DSKeys.KEY_FORMAT_SQL), false);
|
||||
final boolean isShowParams = Convert.toBoolean(setting.remove(DSKeys.KEY_SHOW_PARAMS), false);
|
||||
String sqlLevelStr = setting.remove(DSKeys.KEY_SQL_LEVEL);
|
||||
if (null != sqlLevelStr) {
|
||||
sqlLevelStr = sqlLevelStr.toUpperCase();
|
||||
}
|
||||
final Level level = Convert.toEnum(Level.class, sqlLevelStr, Level.DEBUG);
|
||||
|
||||
final SqlLog sqlLog = new SqlLog();
|
||||
sqlLog.init(isShowSql, isFormatSql, isShowParams, level);
|
||||
|
||||
return new SqlLogFilter(sqlLog);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.db.dialect;
|
||||
|
||||
import org.dromara.hutool.db.DbException;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.sql.Order;
|
||||
@ -54,9 +55,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param entity 数据实体类(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForInsert(Connection conn, Entity entity) throws SQLException;
|
||||
PreparedStatement psForInsert(Connection conn, Entity entity) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于批量插入的PreparedStatement<br>
|
||||
@ -65,9 +66,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param entities 数据实体,实体的结构必须全部一致,否则插入结果将不可预知
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForInsertBatch(Connection conn, Entity... entities) throws SQLException;
|
||||
PreparedStatement psForInsertBatch(Connection conn, Entity... entities) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于删除的{@link PreparedStatement}<br>
|
||||
@ -77,9 +78,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param query 查找条件(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForDelete(Connection conn, Query query) throws SQLException;
|
||||
PreparedStatement psForDelete(Connection conn, Query query) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于更新的{@link PreparedStatement}<br>
|
||||
@ -90,9 +91,9 @@ public interface Dialect extends Serializable {
|
||||
* @param entity 数据实体类(包含表名)
|
||||
* @param query 查找条件(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForUpdate(Connection conn, Entity entity, Query query) throws SQLException;
|
||||
PreparedStatement psForUpdate(Connection conn, Entity entity, Query query) throws DbException;
|
||||
|
||||
// -------------------------------------------- Query
|
||||
|
||||
@ -104,9 +105,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param query 查询条件(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForFind(Connection conn, Query query) throws SQLException;
|
||||
PreparedStatement psForFind(Connection conn, Query query) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于分页查询的{@link PreparedStatement}<br>
|
||||
@ -116,9 +117,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param query 查询条件(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
PreparedStatement psForPage(Connection conn, Query query) throws SQLException;
|
||||
PreparedStatement psForPage(Connection conn, Query query) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于分页查询的{@link PreparedStatement}<br>
|
||||
@ -129,10 +130,10 @@ public interface Dialect extends Serializable {
|
||||
* @param sqlBuilder SQL构建器,可以使用{@link SqlBuilder#of(CharSequence)} 包装普通SQL
|
||||
* @param page 分页对象
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 5.5.3
|
||||
*/
|
||||
PreparedStatement psForPage(Connection conn, SqlBuilder sqlBuilder, Page page) throws SQLException;
|
||||
PreparedStatement psForPage(Connection conn, SqlBuilder sqlBuilder, Page page) throws DbException;
|
||||
|
||||
/**
|
||||
* 构建用于查询行数的{@link PreparedStatement}<br>
|
||||
@ -142,9 +143,9 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param query 查询条件(包含表名)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
default PreparedStatement psForCount(final Connection conn, final Query query) throws SQLException {
|
||||
default PreparedStatement psForCount(final Connection conn, final Query query) throws DbException {
|
||||
return psForCount(conn, SqlBuilder.of().query(query));
|
||||
}
|
||||
|
||||
@ -156,10 +157,10 @@ public interface Dialect extends Serializable {
|
||||
* @param conn 数据库连接对象
|
||||
* @param sqlBuilder 查询语句,应该包含分页等信息
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 5.7.2
|
||||
*/
|
||||
default PreparedStatement psForCount(final Connection conn, SqlBuilder sqlBuilder) throws SQLException {
|
||||
default PreparedStatement psForCount(final Connection conn, SqlBuilder sqlBuilder) throws DbException {
|
||||
// https://gitee.com/dromara/hutool/issues/I713XQ
|
||||
// 为了兼容informix等数据库,此处使用count(*)而非count(1)
|
||||
sqlBuilder = sqlBuilder
|
||||
@ -177,11 +178,11 @@ public interface Dialect extends Serializable {
|
||||
* @param entity 数据实体类(包含表名)
|
||||
* @param keys 查找字段,某些数据库此字段必须,如H2,某些数据库无需此字段,如MySQL(通过主键)
|
||||
* @return PreparedStatement
|
||||
* @throws SQLException SQL执行异常,或方言数据不支持此操作
|
||||
* @throws DbException SQL执行异常,或方言数据不支持此操作
|
||||
* @since 5.7.20
|
||||
*/
|
||||
default PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws SQLException {
|
||||
throw new SQLException("Unsupported upsert operation of " + dialectName());
|
||||
default PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws DbException {
|
||||
throw new DbException("Unsupported upsert operation of " + dialectName());
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,19 +14,12 @@ package org.dromara.hutool.db.dialect;
|
||||
|
||||
import org.dromara.hutool.core.map.SafeConcurrentHashMap;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.driver.DriverUtil;
|
||||
import org.dromara.hutool.db.dialect.impl.AnsiSqlDialect;
|
||||
import org.dromara.hutool.db.dialect.impl.H2Dialect;
|
||||
import org.dromara.hutool.db.dialect.impl.MysqlDialect;
|
||||
import org.dromara.hutool.db.dialect.impl.OracleDialect;
|
||||
import org.dromara.hutool.db.dialect.impl.PhoenixDialect;
|
||||
import org.dromara.hutool.db.dialect.impl.PostgresqlDialect;
|
||||
import org.dromara.hutool.db.dialect.impl.SqlServer2012Dialect;
|
||||
import org.dromara.hutool.db.dialect.impl.Sqlite3Dialect;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.impl.*;
|
||||
import org.dromara.hutool.db.ds.DSWrapper;
|
||||
import org.dromara.hutool.log.LogUtil;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@ -45,11 +38,11 @@ public class DialectFactory implements DriverNamePool {
|
||||
* 根据驱动名创建方言<br>
|
||||
* 驱动名是不分区大小写完全匹配的
|
||||
*
|
||||
* @param driverName JDBC驱动类名
|
||||
* @param dbConfig 数据库配置
|
||||
* @return 方言
|
||||
*/
|
||||
public static Dialect newDialect(final String driverName) {
|
||||
final Dialect dialect = internalNewDialect(driverName);
|
||||
public static Dialect newDialect(final DbConfig dbConfig) {
|
||||
final Dialect dialect = internalNewDialect(dbConfig);
|
||||
LogUtil.debug("Use Dialect: [{}].", dialect.getClass().getSimpleName());
|
||||
return dialect;
|
||||
}
|
||||
@ -58,29 +51,31 @@ public class DialectFactory implements DriverNamePool {
|
||||
* 根据驱动名创建方言<br>
|
||||
* 驱动名是不分区大小写完全匹配的
|
||||
*
|
||||
* @param driverName JDBC驱动类名
|
||||
* @param dbConfig 数据库配置
|
||||
* @return 方言
|
||||
*/
|
||||
private static Dialect internalNewDialect(final String driverName) {
|
||||
private static Dialect internalNewDialect(final DbConfig dbConfig) {
|
||||
final String driverName = dbConfig.getDriver();
|
||||
|
||||
if (StrUtil.isNotBlank(driverName)) {
|
||||
if (DRIVER_MYSQL.equalsIgnoreCase(driverName) || DRIVER_MYSQL_V6.equalsIgnoreCase(driverName)) {
|
||||
return new MysqlDialect();
|
||||
return new MysqlDialect(dbConfig);
|
||||
} else if (DRIVER_ORACLE.equalsIgnoreCase(driverName) || DRIVER_ORACLE_OLD.equalsIgnoreCase(driverName)) {
|
||||
return new OracleDialect();
|
||||
return new OracleDialect(dbConfig);
|
||||
} else if (DRIVER_SQLLITE3.equalsIgnoreCase(driverName)) {
|
||||
return new Sqlite3Dialect();
|
||||
return new Sqlite3Dialect(dbConfig);
|
||||
} else if (DRIVER_POSTGRESQL.equalsIgnoreCase(driverName)) {
|
||||
return new PostgresqlDialect();
|
||||
return new PostgresqlDialect(dbConfig);
|
||||
} else if (DRIVER_H2.equalsIgnoreCase(driverName)) {
|
||||
return new H2Dialect();
|
||||
return new H2Dialect(dbConfig);
|
||||
} else if (DRIVER_SQLSERVER.equalsIgnoreCase(driverName)) {
|
||||
return new SqlServer2012Dialect();
|
||||
return new SqlServer2012Dialect(dbConfig);
|
||||
} else if (DRIVER_PHOENIX.equalsIgnoreCase(driverName)) {
|
||||
return new PhoenixDialect();
|
||||
return new PhoenixDialect(dbConfig);
|
||||
}
|
||||
}
|
||||
// 无法识别可支持的数据库类型默认使用ANSI方言,可兼容大部分SQL语句
|
||||
return new AnsiSqlDialect();
|
||||
return new AnsiSqlDialect(dbConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,17 +103,6 @@ public class DialectFactory implements DriverNamePool {
|
||||
* @return 方言
|
||||
*/
|
||||
public static Dialect newDialect(final DataSource ds) {
|
||||
return newDialect(DriverUtil.identifyDriver(ds));
|
||||
return newDialect(ds instanceof DSWrapper ? ((DSWrapper) ds).getDbConfig() : DbConfig.of());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建方言
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @return 方言
|
||||
*/
|
||||
public static Dialect newDialect(final Connection conn) {
|
||||
return newDialect(DriverUtil.identifyDriver(conn));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.dromara.hutool.db.DbException;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.StatementUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.Dialect;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.Condition;
|
||||
@ -27,7 +28,6 @@ import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* ANSI SQL 方言
|
||||
@ -37,8 +37,18 @@ import java.sql.SQLException;
|
||||
public class AnsiSqlDialect implements Dialect {
|
||||
private static final long serialVersionUID = 2088101129774974580L;
|
||||
|
||||
protected DbConfig dbConfig;
|
||||
protected QuoteWrapper quoteWrapper = new QuoteWrapper();
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public AnsiSqlDialect(final DbConfig dbConfig) {
|
||||
this.dbConfig = dbConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuoteWrapper getWrapper() {
|
||||
return this.quoteWrapper;
|
||||
@ -53,7 +63,7 @@ public class AnsiSqlDialect implements Dialect {
|
||||
public PreparedStatement psForInsert(final Connection conn, final Entity entity) {
|
||||
final SqlBuilder insert = SqlBuilder.of(quoteWrapper).insert(entity, this.dialectName());
|
||||
|
||||
return StatementUtil.prepareStatement(conn, insert);
|
||||
return StatementUtil.prepareStatement(this.dbConfig.isReturnGeneratedKey(), this.dbConfig, conn, insert.build(), insert.getParamValueArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -63,36 +73,35 @@ public class AnsiSqlDialect implements Dialect {
|
||||
}
|
||||
// 批量,根据第一行数据结构生成SQL占位符
|
||||
final SqlBuilder insert = SqlBuilder.of(quoteWrapper).insert(entities[0], this.dialectName());
|
||||
return StatementUtil.prepareStatementForBatch(conn, insert.build(), entities);
|
||||
return StatementUtil.prepareStatementForBatch(this.dbConfig, conn, insert.build(), entities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement psForDelete(final Connection conn, final Query query) throws SQLException {
|
||||
public PreparedStatement psForDelete(final Connection conn, final Query query) throws DbException {
|
||||
Assert.notNull(query, "query must be not null !");
|
||||
|
||||
final Condition[] where = query.getWhere();
|
||||
if (ArrayUtil.isEmpty(where)) {
|
||||
// 对于无条件删除语句直接抛出异常禁止,防止误删除
|
||||
throw new SQLException("No 'WHERE' condition, we can't prepared statement for delete everything.");
|
||||
throw new DbException("No 'WHERE' condition, we can't prepared statement for delete everything.");
|
||||
}
|
||||
final SqlBuilder delete = SqlBuilder.of(quoteWrapper).delete(query.getFirstTableName()).where(where);
|
||||
|
||||
return StatementUtil.prepareStatement(conn, delete);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, delete.build(), delete.getParamValueArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement psForUpdate(final Connection conn, final Entity entity, final Query query) throws SQLException {
|
||||
public PreparedStatement psForUpdate(final Connection conn, final Entity entity, final Query query) throws DbException {
|
||||
Assert.notNull(query, "query must be not null !");
|
||||
|
||||
final Condition[] where = query.getWhere();
|
||||
if (ArrayUtil.isEmpty(where)) {
|
||||
// 对于无条件地删除语句直接抛出异常禁止,防止误删除
|
||||
throw new SQLException("No 'WHERE' condition, we can't prepare statement for update everything.");
|
||||
throw new DbException("No 'WHERE' condition, we can't prepare statement for update everything.");
|
||||
}
|
||||
|
||||
final SqlBuilder update = SqlBuilder.of(quoteWrapper).update(entity).where(where);
|
||||
|
||||
return StatementUtil.prepareStatement(conn, update);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, update.build(), update.getParamValueArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,7 +126,7 @@ public class AnsiSqlDialect implements Dialect {
|
||||
if (null != page) {
|
||||
sqlBuilder = wrapPageSql(sqlBuilder.orderBy(page.getOrders()), page);
|
||||
}
|
||||
return StatementUtil.prepareStatement(conn, sqlBuilder);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, sqlBuilder.build(), sqlBuilder.getParamValueArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.StatementUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
|
||||
@ -34,8 +35,11 @@ public class H2Dialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 数据库配置
|
||||
*/
|
||||
public H2Dialect() {
|
||||
public H2Dialect(final DbConfig config) {
|
||||
super(config);
|
||||
// wrapper = new Wrapper('"');
|
||||
}
|
||||
|
||||
@ -87,6 +91,6 @@ public class H2Dialect extends AnsiSqlDialect {
|
||||
// 更新值列表
|
||||
.append(") VALUES (").append(placeHolder).append(")");
|
||||
|
||||
return StatementUtil.prepareStatement(conn, builder);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, builder.build(), builder.getParamValueArray());
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.StatementUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.QuoteWrapper;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
@ -33,8 +34,11 @@ public class MysqlDialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public MysqlDialect() {
|
||||
public MysqlDialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
quoteWrapper = new QuoteWrapper('`');
|
||||
}
|
||||
|
||||
@ -100,6 +104,6 @@ public class MysqlDialect extends AnsiSqlDialect {
|
||||
// 主键冲突后的更新操作
|
||||
.append(") ON DUPLICATE KEY UPDATE ").append(updateHolder);
|
||||
|
||||
return StatementUtil.prepareStatement(conn, builder);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, builder.build(), builder.getParamValueArray());
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ package org.dromara.hutool.db.dialect.impl;
|
||||
import org.dromara.hutool.core.text.StrPool;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
|
||||
@ -43,8 +44,11 @@ public class OracleDialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public OracleDialect() {
|
||||
public OracleDialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
//Oracle所有字段名用双引号包围,防止字段名或表名与系统关键字冲突
|
||||
//wrapper = new Wrapper('"');
|
||||
}
|
||||
|
@ -12,13 +12,14 @@
|
||||
|
||||
package org.dromara.hutool.db.dialect.impl;
|
||||
|
||||
import org.dromara.hutool.db.DbException;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.Query;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Phoenix数据库方言
|
||||
@ -31,13 +32,15 @@ public class PhoenixDialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public PhoenixDialect() {
|
||||
public PhoenixDialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
// wrapper = new Wrapper('"');
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement psForUpdate(final Connection conn, final Entity entity, final Query query) throws SQLException {
|
||||
public PreparedStatement psForUpdate(final Connection conn, final Entity entity, final Query query) throws DbException {
|
||||
// Phoenix的插入、更新语句是统一的,统一使用upsert into关键字
|
||||
// Phoenix只支持通过主键更新操作,因此query无效,自动根据entity中的主键更新
|
||||
return super.psForInsert(conn, entity);
|
||||
@ -49,7 +52,7 @@ public class PhoenixDialect extends AnsiSqlDialect {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws SQLException {
|
||||
public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws DbException {
|
||||
// Phoenix只支持通过主键更新操作,因此query无效,自动根据entity中的主键更新
|
||||
return psForInsert(conn, entity);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.Entity;
|
||||
import org.dromara.hutool.db.StatementUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.QuoteWrapper;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
@ -36,8 +37,10 @@ public class PostgresqlDialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public PostgresqlDialect() {
|
||||
public PostgresqlDialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
quoteWrapper = new QuoteWrapper(CharUtil.DOUBLE_QUOTES);
|
||||
}
|
||||
|
||||
@ -89,6 +92,6 @@ public class PostgresqlDialect extends AnsiSqlDialect {
|
||||
// 主键冲突后的更新操作
|
||||
.append(") DO UPDATE SET ").append(updateHolder);
|
||||
|
||||
return StatementUtil.prepareStatement(conn, builder);
|
||||
return StatementUtil.prepareStatement(false, this.dbConfig, conn, builder.build(), builder.getParamValueArray());
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ package org.dromara.hutool.db.dialect.impl;
|
||||
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.db.Page;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.SqlBuilder;
|
||||
import org.dromara.hutool.db.sql.QuoteWrapper;
|
||||
@ -28,8 +29,10 @@ public class SqlServer2012Dialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public SqlServer2012Dialect() {
|
||||
public SqlServer2012Dialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
//双引号和中括号适用,双引号更广泛
|
||||
quoteWrapper = new QuoteWrapper('"');
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
package org.dromara.hutool.db.dialect.impl;
|
||||
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.dialect.DialectName;
|
||||
import org.dromara.hutool.db.sql.QuoteWrapper;
|
||||
|
||||
@ -25,8 +26,11 @@ public class Sqlite3Dialect extends AnsiSqlDialect {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param dbConfig 数据库配置
|
||||
*/
|
||||
public Sqlite3Dialect() {
|
||||
public Sqlite3Dialect(final DbConfig dbConfig) {
|
||||
super(dbConfig);
|
||||
quoteWrapper = new QuoteWrapper('[', ']');
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,9 @@ public class NumberHandler implements RsHandler<Number>{
|
||||
private static final long serialVersionUID = 4081498054379705596L;
|
||||
|
||||
/**
|
||||
* 创建一个 NumberHandler对象
|
||||
* @return NumberHandler对象
|
||||
* 单例
|
||||
*/
|
||||
public static NumberHandler of() {
|
||||
return new NumberHandler();
|
||||
}
|
||||
public static final NumberHandler INSTANCE = new NumberHandler();
|
||||
|
||||
@Override
|
||||
public Number handle(final ResultSet rs) throws SQLException {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Copyright (c) 2024. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
@ -13,38 +13,63 @@
|
||||
package org.dromara.hutool.db.sql;
|
||||
|
||||
import org.dromara.hutool.core.collection.iter.ArrayIter;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.func.SerFunction;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.db.DbException;
|
||||
import org.dromara.hutool.db.StatementUtil;
|
||||
import org.dromara.hutool.db.config.DbConfig;
|
||||
import org.dromara.hutool.db.handler.RsHandler;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* SQL执行器,全部为静态方法,执行查询或非查询的SQL语句<br>
|
||||
* 此方法为JDBC的简单封装,与数据库类型无关
|
||||
* SQL执行器,用于执行指定的SQL查询、更新语句。<br>
|
||||
* 此执行器执行原始SQL。
|
||||
*
|
||||
* @author loolly
|
||||
* @author Looly
|
||||
*/
|
||||
public class SqlExecutor {
|
||||
|
||||
/**
|
||||
* 执行非查询语句<br>
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
* 创建SqlExecutor
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL,使用name做为占位符,例如:name
|
||||
* @param paramMap 参数Map
|
||||
* @return 影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.0.10
|
||||
* @param config 配置
|
||||
* @param conn {@link Connection}
|
||||
* @return SqlExecutor
|
||||
*/
|
||||
public static int execute(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbException {
|
||||
final NamedSql namedSql = new NamedSql(sql, paramMap);
|
||||
return execute(conn, namedSql.getSql(), namedSql.getParamArray());
|
||||
public static SqlExecutor of(final DbConfig config, final Connection conn) {
|
||||
return new SqlExecutor(config, conn);
|
||||
}
|
||||
|
||||
private final DbConfig config;
|
||||
private final Connection conn;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 配置
|
||||
* @param conn {@link Connection}
|
||||
*/
|
||||
public SqlExecutor(final DbConfig config, final Connection conn) {
|
||||
this.config = config;
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行非查询语句<br>
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param sql SQL,使用name做为占位符,例如:name
|
||||
* @param paramMap 参数Map
|
||||
* @return 影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.0.10
|
||||
*/
|
||||
public int execute(final String sql, final Map<String, Object> paramMap) throws DbException {
|
||||
final NamedSql namedSql = new NamedSql(sql, paramMap);
|
||||
return execute(namedSql.getSql(), namedSql.getParamArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,16 +77,15 @@ public class SqlExecutor {
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @return 影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static int execute(final Connection conn, final String sql, final Object... params) throws DbException {
|
||||
public int execute(final String sql, final Object... params) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = StatementUtil.prepareStatement(false, conn, sql, params);
|
||||
ps = StatementUtil.prepareStatement(false, this.config, this.conn, sql, params);
|
||||
return ps.executeUpdate();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
@ -74,16 +98,15 @@ public class SqlExecutor {
|
||||
* 执行调用存储过程<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @return 如果执行后第一个结果是ResultSet,则返回true,否则返回false。
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static boolean call(final Connection conn, final String sql, final Object... params) throws DbException {
|
||||
public boolean call(final String sql, final Object... params) throws DbException {
|
||||
CallableStatement call = null;
|
||||
try {
|
||||
call = StatementUtil.prepareCall(conn, sql, params);
|
||||
call = StatementUtil.prepareCall(this.config, this.conn, sql, params);
|
||||
return call.execute();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
@ -96,16 +119,15 @@ public class SqlExecutor {
|
||||
* 执行调用存储过程<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @return ResultSet
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.1.4
|
||||
*/
|
||||
public static ResultSet callQuery(final Connection conn, final String sql, final Object... params) throws DbException {
|
||||
public ResultSet callQuery(final String sql, final Object... params) throws DbException {
|
||||
try {
|
||||
return StatementUtil.prepareCall(conn, sql, params).executeQuery();
|
||||
return StatementUtil.prepareCall(this.config, this.conn, sql, params).executeQuery();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@ -116,16 +138,15 @@ public class SqlExecutor {
|
||||
* 发查询语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param paramMap 参数Map
|
||||
* @return 主键
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.0.10
|
||||
*/
|
||||
public static Long executeForGeneratedKey(final Connection conn, final String sql, final Map<String, Object> paramMap) throws DbException {
|
||||
public Long executeForGeneratedKey(final String sql, final Map<String, Object> paramMap) throws DbException {
|
||||
final NamedSql namedSql = new NamedSql(sql, paramMap);
|
||||
return executeForGeneratedKey(conn, namedSql.getSql(), namedSql.getParamArray());
|
||||
return executeForGeneratedKey(namedSql.getSql(), namedSql.getParamArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,32 +154,21 @@ public class SqlExecutor {
|
||||
* 发查询语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param params 参数
|
||||
* @return 主键
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static Long executeForGeneratedKey(final Connection conn, final String sql, final Object... params) throws DbException {
|
||||
public Long executeForGeneratedKey(final String sql, final Object... params) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
ps = StatementUtil.prepareStatement(true, conn, sql, params);
|
||||
ps = StatementUtil.prepareStatement(true, this.config, this.conn, sql, params);
|
||||
ps.executeUpdate();
|
||||
rs = ps.getGeneratedKeys();
|
||||
if (rs != null && rs.next()) {
|
||||
try {
|
||||
return rs.getLong(1);
|
||||
} catch (final SQLException e) {
|
||||
// 可能会出现没有主键返回的情况
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return StatementUtil.getGeneratedKeyOfLong(ps);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(ps);
|
||||
IoUtil.closeQuietly(rs);
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,16 +177,15 @@ public class SqlExecutor {
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql SQL
|
||||
* @param paramsBatch 批量的参数
|
||||
* @return 每个SQL执行影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static int[] executeBatch(final Connection conn, final String sql, final Iterable<Object[]> paramsBatch) throws DbException {
|
||||
public int[] executeBatch(final String sql, final Iterable<Object[]> paramsBatch) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = StatementUtil.prepareStatementForBatch(conn, sql, paramsBatch);
|
||||
ps = StatementUtil.prepareStatementForBatch(this.config, this.conn, sql, paramsBatch);
|
||||
return ps.executeBatch();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
@ -190,14 +199,13 @@ public class SqlExecutor {
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sqls SQL列表
|
||||
* @return 每个SQL执行影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.5.6
|
||||
*/
|
||||
public static int[] executeBatch(final Connection conn, final String... sqls) throws DbException {
|
||||
return executeBatch(conn, new ArrayIter<>(sqls));
|
||||
public int[] executeBatch(final String... sqls) throws DbException {
|
||||
return executeBatch(new ArrayIter<>(sqls));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,16 +213,15 @@ public class SqlExecutor {
|
||||
* 语句包括 插入、更新、删除<br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param conn 数据库连接对象
|
||||
* @param sqls SQL列表
|
||||
* @return 每个SQL执行影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.5.6
|
||||
*/
|
||||
public static int[] executeBatch(final Connection conn, final Iterable<String> sqls) throws DbException {
|
||||
public int[] executeBatch(final Iterable<String> sqls) throws DbException {
|
||||
Statement statement = null;
|
||||
try {
|
||||
statement = conn.createStatement();
|
||||
statement = this.conn.createStatement();
|
||||
for (final String sql : sqls) {
|
||||
statement.addBatch(sql);
|
||||
}
|
||||
@ -226,12 +233,13 @@ public class SqlExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
// region ----- query
|
||||
|
||||
/**
|
||||
* 执行查询语句,例如:select * from table where field1=:name1 <br>
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql 查询语句,使用参数名占位符,例如:name
|
||||
* @param rsh 结果集处理对象
|
||||
* @param paramMap 参数对
|
||||
@ -239,9 +247,9 @@ public class SqlExecutor {
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.0.10
|
||||
*/
|
||||
public static <T> T query(final Connection conn, final String sql, final RsHandler<T> rsh, final Map<String, Object> paramMap) throws DbException {
|
||||
public <T> T query(final String sql, final RsHandler<T> rsh, final Map<String, Object> paramMap) throws DbException {
|
||||
final NamedSql namedSql = new NamedSql(sql, paramMap);
|
||||
return query(conn, namedSql.getSql(), rsh, namedSql.getParamArray());
|
||||
return query(namedSql.getSql(), rsh, namedSql.getParamArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -249,15 +257,14 @@ public class SqlExecutor {
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param conn 数据库连接对象
|
||||
* @param sqlBuilder SQL构建器,包含参数
|
||||
* @param rsh 结果集处理对象
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 5.5.3
|
||||
*/
|
||||
public static <T> T query(final Connection conn, final SqlBuilder sqlBuilder, final RsHandler<T> rsh) throws DbException {
|
||||
return query(conn, sqlBuilder.build(), rsh, sqlBuilder.getParamValueArray());
|
||||
public <T> T query(final SqlBuilder sqlBuilder, final RsHandler<T> rsh) throws DbException {
|
||||
return query(sqlBuilder.build(), rsh, sqlBuilder.getParamValueArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,18 +272,17 @@ public class SqlExecutor {
|
||||
* 此方法不会关闭Connection
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param conn 数据库连接对象
|
||||
* @param sql 查询语句
|
||||
* @param rsh 结果集处理对象
|
||||
* @param params 参数
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static <T> T query(final Connection conn, final String sql, final RsHandler<T> rsh, final Object... params) throws DbException {
|
||||
public <T> T query(final String sql, final RsHandler<T> rsh, final Object... params) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = StatementUtil.prepareStatement(false, conn, sql, params);
|
||||
return executeQuery(ps, rsh);
|
||||
ps = StatementUtil.prepareStatement(false, this.config, this.conn, sql, params);
|
||||
return StatementUtil.executeQuery(ps, rsh);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(ps);
|
||||
}
|
||||
@ -287,124 +293,20 @@ public class SqlExecutor {
|
||||
* 此方法主要用于自定义场景,如游标查询等
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param conn 数据库连接对象
|
||||
* @param statementFunc 自定义{@link PreparedStatement}创建函数
|
||||
* @param rsh 自定义结果集处理
|
||||
* @return 结果
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 5.7.17
|
||||
*/
|
||||
public static <T> T query(final Connection conn, final SerFunction<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbException {
|
||||
public <T> T query(final SerFunction<Connection, PreparedStatement> statementFunc, final RsHandler<T> rsh) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
ps = statementFunc.apply(conn);
|
||||
return executeQuery(ps, rsh);
|
||||
return StatementUtil.executeQuery(ps, rsh);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(ps);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------- Execute With PreparedStatement
|
||||
|
||||
/**
|
||||
* 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句,例如 CREATE TABLE 和 DROP TABLE。<br>
|
||||
* INSERT、UPDATE 或 DELETE 语句的效果是修改表中零行或多行中的一列或多列。<br>
|
||||
* executeUpdate 的返回值是一个整数(int),指示受影响的行数(即更新计数)。<br>
|
||||
* 对于 CREATE TABLE 或 DROP TABLE 等不操作行的语句,executeUpdate 的返回值总为零。<br>
|
||||
* 此方法不会关闭PreparedStatement
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param params 参数
|
||||
* @return 影响的行数
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static int executeUpdate(final PreparedStatement ps, final Object... params) throws DbException {
|
||||
try {
|
||||
StatementUtil.fillArrayParam(ps, params);
|
||||
return ps.executeUpdate();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 可用于执行任何SQL语句,返回一个boolean值,表明执行该SQL语句是否返回了ResultSet。<br>
|
||||
* 如果执行后第一个结果是ResultSet,则返回true,否则返回false。<br>
|
||||
* 此方法不会关闭PreparedStatement
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param params 参数
|
||||
* @return 如果执行后第一个结果是ResultSet,则返回true,否则返回false。
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static boolean execute(final PreparedStatement ps, final Object... params) throws DbException {
|
||||
try {
|
||||
StatementUtil.fillArrayParam(ps, params);
|
||||
return ps.execute();
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询语句<br>
|
||||
* 此方法不会关闭PreparedStatement
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param ps PreparedStatement
|
||||
* @param rsh 结果集处理对象
|
||||
* @param params 参数
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static <T> T query(final PreparedStatement ps, final RsHandler<T> rsh, final Object... params) throws DbException {
|
||||
try {
|
||||
StatementUtil.fillArrayParam(ps, params);
|
||||
return executeQuery(ps, rsh);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行查询语句并关闭PreparedStatement
|
||||
*
|
||||
* @param <T> 处理结果类型
|
||||
* @param ps PreparedStatement
|
||||
* @param rsh 结果集处理对象
|
||||
* @param params 参数
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
*/
|
||||
public static <T> T queryAndClosePs(final PreparedStatement ps, final RsHandler<T> rsh, final Object... params) throws DbException {
|
||||
try {
|
||||
return query(ps, rsh, params);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(ps);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------------- Private method start
|
||||
|
||||
/**
|
||||
* 执行查询
|
||||
*
|
||||
* @param ps {@link PreparedStatement}
|
||||
* @param rsh 结果集处理对象
|
||||
* @return 结果对象
|
||||
* @throws DbException SQL执行异常
|
||||
* @since 4.1.13
|
||||
*/
|
||||
private static <T> T executeQuery(final PreparedStatement ps, final RsHandler<T> rsh) throws DbException {
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
rs = ps.executeQuery();
|
||||
return rsh.handle(rs);
|
||||
} catch (final SQLException e) {
|
||||
throw new DbException(e);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(rs);
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------------------------------------------------------------- Private method end
|
||||
// endregion
|
||||
}
|
||||
|
@ -23,11 +23,6 @@ import org.dromara.hutool.log.level.Level;
|
||||
*/
|
||||
public class SqlLog {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final SqlLog INSTANCE = new SqlLog();
|
||||
|
||||
private final static Log log = Log.get();
|
||||
|
||||
/**
|
||||
|
@ -205,14 +205,16 @@ public class StatementBuilder implements Builder<StatementWrapper> {
|
||||
params = namedSql.getParamArray();
|
||||
}
|
||||
|
||||
sqlFilter.filter(this.connection, this.boundSql, this.returnGeneratedKey);
|
||||
if(null != this.sqlFilter){
|
||||
this.sqlFilter.filter(this.connection, this.boundSql, this.returnGeneratedKey);
|
||||
}
|
||||
|
||||
final PreparedStatement ps;
|
||||
if (returnGeneratedKey && StrUtil.startWithIgnoreCase(sql, "insert")) {
|
||||
if (this.returnGeneratedKey && StrUtil.startWithIgnoreCase(sql, "insert")) {
|
||||
// 插入默认返回主键
|
||||
ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||
ps = this.connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
|
||||
} else {
|
||||
ps = connection.prepareStatement(sql);
|
||||
ps = this.connection.prepareStatement(sql);
|
||||
}
|
||||
|
||||
return StatementWrapper.of(ps).fillArrayParam(params);
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
package org.dromara.hutool.db.sql.filter;
|
||||
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.db.sql.BoundSql;
|
||||
import org.dromara.hutool.db.sql.SqlLog;
|
||||
|
||||
@ -25,20 +24,8 @@ import java.sql.Connection;
|
||||
*/
|
||||
public class SqlLogFilter implements SqlFilter {
|
||||
|
||||
/**
|
||||
* 单例
|
||||
*/
|
||||
public static final SqlLogFilter INSTANCE = new SqlLogFilter();
|
||||
|
||||
private final SqlLog sqlLog;
|
||||
|
||||
/**
|
||||
* 构造,使用默认SqlLog
|
||||
*/
|
||||
public SqlLogFilter() {
|
||||
this(SqlLog.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user