From 3b38125d4e59ad7493189a153958f8178eafe80e Mon Sep 17 00:00:00 2001 From: Looly Date: Wed, 16 Jun 2021 19:06:26 +0800 Subject: [PATCH] fix count --- CHANGELOG.md | 1 + .../main/java/cn/hutool/db/AbstractDb.java | 19 ------------ .../main/java/cn/hutool/db/DialectRunner.java | 24 +++++++++++++++ .../main/java/cn/hutool/db/SqlConnRunner.java | 30 +------------------ .../java/cn/hutool/db/dialect/Dialect.java | 17 +++++++++++ 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74165a24f..eba4a2309 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * 【core 】 增加UserPassAuthenticator ### 🐞Bug修复 +* 【db 】 修复Oracle下别名错误造成的SQL语法啊错误(issue#I3VTQW@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java index 51d8e3d91..77c20fcc4 100644 --- a/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java +++ b/hutool-db/src/main/java/cn/hutool/db/AbstractDb.java @@ -856,25 +856,6 @@ public abstract class AbstractDb implements Serializable { } } - /** - * 分页查询 - * - * @param sql SQL语句字符串 - * @param page 分页对象 - * @return 结果对象 - * @throws SQLException SQL执行异常 - * @since 5.5.3 - */ - public PageResult page(CharSequence sql, Page page) throws SQLException { - Connection conn = null; - try { - conn = this.getConnection(); - return runner.page(conn, SqlBuilder.of(sql), page); - } finally { - this.closeConnection(conn); - } - } - /** * 分页查询 * diff --git a/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java b/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java index 7dd8ff710..43d0574e3 100644 --- a/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java +++ b/hutool-db/src/main/java/cn/hutool/db/DialectRunner.java @@ -208,6 +208,30 @@ public class DialectRunner implements Serializable { return SqlExecutor.queryAndClosePs(dialect.psForCount(conn, Query.of(where)), new NumberHandler()).longValue(); } + /** + * 获取查询结果总数,生成类似于 SELECT count(1) from (sql) hutool_alias_count_
+ * 此方法会重新构建{@link SqlBuilder},并去除末尾的order by子句 + * + * @param conn 数据库连接对象 + * @param sqlBuilder 查询语句 + * @return 复合条件的结果数 + * @throws SQLException SQL执行异常 + * @since 5.7.2 + */ + public long count(Connection conn, SqlBuilder sqlBuilder) throws SQLException { + checkConn(conn); + + String selectSql = sqlBuilder.build(); + // 去除order by 子句 + final int orderByIndex = StrUtil.indexOfIgnoreCase(selectSql, " order by"); + if (orderByIndex > 0) { + selectSql = StrUtil.subPre(selectSql, orderByIndex); + } + return SqlExecutor.queryAndClosePs(dialect.psForCount(conn, + SqlBuilder.of(selectSql).addParams(sqlBuilder.getParamValueArray())), + new NumberHandler()).longValue(); + } + /** * 分页查询
* 此方法不会关闭Connection diff --git a/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java b/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java index 3cac0b63f..e21d8c5af 100644 --- a/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java +++ b/hutool-db/src/main/java/cn/hutool/db/SqlConnRunner.java @@ -1,14 +1,11 @@ package cn.hutool.db; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.StrUtil; import cn.hutool.db.dialect.Dialect; import cn.hutool.db.dialect.DialectFactory; import cn.hutool.db.handler.EntityListHandler; import cn.hutool.db.handler.HandleHelper; -import cn.hutool.db.handler.NumberHandler; import cn.hutool.db.handler.PageResultHandler; import cn.hutool.db.handler.RsHandler; import cn.hutool.db.sql.Condition.LikeType; @@ -280,19 +277,6 @@ public class SqlConnRunner extends DialectRunner { return findAll(conn, Entity.create(tableName).set(field, values)); } - /** - * 获取查询结果总数,生成类似于 SELECT count(1) from (sql) as _count - * - * @param conn 数据库连接对象 - * @param sqlBuilder SQL构建器,包括SQL和参数 - * @return 结果数 - * @throws SQLException SQL异常 - * @since 5.7.0 - */ - public long count(Connection conn, SqlBuilder sqlBuilder) throws SQLException { - return count(conn, sqlBuilder.build(), sqlBuilder.getParamValueArray()); - } - /** * 获取查询结果总数,生成类似于 SELECT count(1) from (sql) as _count * @@ -304,19 +288,7 @@ public class SqlConnRunner extends DialectRunner { * @since 5.6.6 */ public long count(Connection conn, CharSequence selectSql, Object... params) throws SQLException { - Assert.notBlank(selectSql, "Select SQL must be not blank!"); - final int orderByIndex = StrUtil.indexOfIgnoreCase(selectSql, " order by"); - if (orderByIndex > 0) { - selectSql = StrUtil.subPre(selectSql, orderByIndex); - } - - SqlBuilder sqlBuilder = SqlBuilder.of(selectSql) - .insertPreFragment("SELECT count(1) from(") - // issue#I3IJ8X@Gitee,在子查询时需设置单独别名,此处为了防止和用户的表名冲突,使用自定义的较长别名 - .append(") as _hutool_alias_count_") - // 添加参数 - .addParams(params); - return page(conn, sqlBuilder, null, new NumberHandler()).intValue(); + return count(conn, SqlBuilder.of(selectSql).addParams(params)); } /** diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/Dialect.java b/hutool-db/src/main/java/cn/hutool/db/dialect/Dialect.java index 08677c1e8..7eacc8d14 100644 --- a/hutool-db/src/main/java/cn/hutool/db/dialect/Dialect.java +++ b/hutool-db/src/main/java/cn/hutool/db/dialect/Dialect.java @@ -126,6 +126,23 @@ public interface Dialect extends Serializable { return psForFind(conn, query); } + /** + * 构建用于查询行数的PreparedStatement + * + * @param conn 数据库连接对象 + * @param sqlBuilder 查询语句,应该包含分页等信息 + * @return PreparedStatement + * @throws SQLException SQL执行异常 + * @since 5.7.2 + */ + default PreparedStatement psForCount(Connection conn, SqlBuilder sqlBuilder) throws SQLException{ + sqlBuilder = sqlBuilder + .insertPreFragment("SELECT count(1) from(") + // issue#I3IJ8X@Gitee,在子查询时需设置单独别名,此处为了防止和用户的表名冲突,使用自定义的较长别名 + .append(") hutool_alias_count_"); + return psForPage(conn, sqlBuilder, null); + } + /** * 方言名 *