fix count

This commit is contained in:
Looly 2021-06-16 19:06:26 +08:00
parent ad49bb9393
commit 3b38125d4e
5 changed files with 43 additions and 48 deletions

View File

@ -9,6 +9,7 @@
* 【core 】 增加UserPassAuthenticator
### 🐞Bug修复
* 【db 】 修复Oracle下别名错误造成的SQL语法啊错误issue#I3VTQW@Gitee
-------------------------------------------------------------------------------------------------------------

View File

@ -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<Entity> 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);
}
}
/**
* 分页查询
*

View File

@ -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_<br>
* 此方法会重新构建{@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();
}
/**
* 分页查询<br>
* 此方法不会关闭Connection

View File

@ -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));
}
/**

View File

@ -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);
}
/**
* 方言名
*