|
@@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
-import javax.sql.DataSource;
|
|
|
|
|
import java.io.*;
|
|
import java.io.*;
|
|
|
import java.sql.*;
|
|
import java.sql.*;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
@@ -678,7 +677,7 @@ public class PrintServiceImpl implements PrintService {
|
|
|
@Override
|
|
@Override
|
|
|
public int getCount(String userName, String profile, String reportName, String whereCondition,
|
|
public int getCount(String userName, String profile, String reportName, String whereCondition,
|
|
|
String otherParameters) throws SQLException, IOException, DocumentException {
|
|
String otherParameters) throws SQLException, IOException, DocumentException {
|
|
|
- DataSource dataSource = MasterManager.getDataSource(userName, profile);
|
|
|
|
|
|
|
+ DruidDataSource dataSource = MasterManager.getDataSource(userName, profile);
|
|
|
if (dataSource == null) {
|
|
if (dataSource == null) {
|
|
|
throw new SQLException("获取数据源失败");
|
|
throw new SQLException("获取数据源失败");
|
|
|
}
|
|
}
|
|
@@ -696,7 +695,7 @@ public class PrintServiceImpl implements PrintService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 因为子报表数据量较小,而且其参数来自主报表,无法简单地进行判断,所以不判断子报表是否过载
|
|
// 因为子报表数据量较小,而且其参数来自主报表,无法简单地进行判断,所以不判断子报表是否过载
|
|
|
- int count = getCount(jrxmlFilePath, whereCondition, otherParameters, connection);
|
|
|
|
|
|
|
+ int count = getCount(jrxmlFilePath, whereCondition, otherParameters, connection, dataSource.getDbType());
|
|
|
logger.info("count... " + count);
|
|
logger.info("count... " + count);
|
|
|
return count;
|
|
return count;
|
|
|
} finally {
|
|
} finally {
|
|
@@ -713,11 +712,12 @@ public class PrintServiceImpl implements PrintService {
|
|
|
* @param whereCondition
|
|
* @param whereCondition
|
|
|
* @param otherParameters
|
|
* @param otherParameters
|
|
|
* @param connection
|
|
* @param connection
|
|
|
|
|
+ * @param dbType
|
|
|
* @throws IOException
|
|
* @throws IOException
|
|
|
* @throws SQLException
|
|
* @throws SQLException
|
|
|
* @throws DocumentException
|
|
* @throws DocumentException
|
|
|
*/
|
|
*/
|
|
|
- private int getCount(String jrxmlFilePath, String whereCondition, String otherParameters, Connection connection)
|
|
|
|
|
|
|
+ private int getCount(String jrxmlFilePath, String whereCondition, String otherParameters, Connection connection, String dbType)
|
|
|
throws IOException, SQLException, DocumentException {
|
|
throws IOException, SQLException, DocumentException {
|
|
|
XMLWriter xmlWriter = null;
|
|
XMLWriter xmlWriter = null;
|
|
|
try {
|
|
try {
|
|
@@ -736,7 +736,7 @@ public class PrintServiceImpl implements PrintService {
|
|
|
queryString = queryString.replace("$P!{WHERE_CONDITION}", whereCondition);
|
|
queryString = queryString.replace("$P!{WHERE_CONDITION}", whereCondition);
|
|
|
}
|
|
}
|
|
|
queryString = replaceOtherParameters(queryString, otherParameters);
|
|
queryString = replaceOtherParameters(queryString, otherParameters);
|
|
|
- return getCount(connection, queryString);
|
|
|
|
|
|
|
+ return getCount(connection, queryString, dbType);
|
|
|
} finally {
|
|
} finally {
|
|
|
if (xmlWriter != null) {
|
|
if (xmlWriter != null) {
|
|
|
xmlWriter.close();
|
|
xmlWriter.close();
|
|
@@ -783,39 +783,48 @@ public class PrintServiceImpl implements PrintService {
|
|
|
*
|
|
*
|
|
|
* @param connection
|
|
* @param connection
|
|
|
* @param sql
|
|
* @param sql
|
|
|
|
|
+ * @param dbType
|
|
|
* @return
|
|
* @return
|
|
|
* @throws SQLException
|
|
* @throws SQLException
|
|
|
*/
|
|
*/
|
|
|
- private int getCount(Connection connection, String sql) throws SQLException {
|
|
|
|
|
|
|
+ private int getCount(Connection connection, String sql, String dbType) throws SQLException {
|
|
|
PreparedStatement preparedStatement = null;
|
|
PreparedStatement preparedStatement = null;
|
|
|
ResultSet resultSet = null;
|
|
ResultSet resultSet = null;
|
|
|
try {
|
|
try {
|
|
|
- // 如果直接在 sql 外用 count(1) 统计数目,当关联表多时,可能会出现错误
|
|
|
|
|
- // ORA-01792: 表或视图中的最大列数为 1000
|
|
|
|
|
- // 报错主要发生在类似 select * 的情况下,但是不能直接这样判断,因为可能存在
|
|
|
|
|
- // 1. select tt.*, pi_id from purchase t left join
|
|
|
|
|
- // 2. union
|
|
|
|
|
- // 这样的情况,很难区分,因此
|
|
|
|
|
- // 1. 对于普通 sql ,将 select 后的字段改为 count(1)
|
|
|
|
|
- // 2. 而最外层含有 group by 的 sql ,直接改为 count(1) 可能得到不止一行,结果也并非实际行数。再加上
|
|
|
|
|
- // group by 的结果列数一般很小,所以可以在外面使用 count(1) ,一般不会超出 1000 行
|
|
|
|
|
- // 3. union 外层使用 count(1)
|
|
|
|
|
String lowerSql = sql.toLowerCase();
|
|
String lowerSql = sql.toLowerCase();
|
|
|
- if (!lowerSql.matches("[\\s\\S]+?group[\\s]+?by[\\s]+?[^)]+?")
|
|
|
|
|
- && !lowerSql.matches("[\\s\\S]+?[\\s]+?union[\\s]+?[\\s\\S]+?")) {
|
|
|
|
|
- String regex = "([\\s\\S]+?from)[\\s]+?[^,]+?";
|
|
|
|
|
- Pattern pattern = Pattern.compile(regex);
|
|
|
|
|
- Matcher matcher = pattern.matcher(lowerSql);
|
|
|
|
|
- if (matcher.find()) {
|
|
|
|
|
- int start = matcher.start(1);
|
|
|
|
|
- int end = matcher.end(1);
|
|
|
|
|
- sql = sql.substring(0, start) + "select count(1) from" + sql.substring(end);
|
|
|
|
|
|
|
+ if (JdbcUtils.MYSQL.equals(dbType)) {
|
|
|
|
|
+ // 如果 sql 使用 limit 限定了数目,将 select 后的字段改为 count(1) 所统计的数目并不对
|
|
|
|
|
+ sql = "select count(1) from (" + sql + ") as tbalias";
|
|
|
|
|
+ } else if (JdbcUtils.ORACLE.equals(dbType)) {
|
|
|
|
|
+ // 如果直接在 sql 外用 count(1) 统计数目,当关联表多时,可能会出现错误
|
|
|
|
|
+ // ORA-01792: 表或视图中的最大列数为 1000
|
|
|
|
|
+ // 报错主要发生在类似 select * 的情况下,但是不能直接这样判断,因为可能存在
|
|
|
|
|
+ // 1. select tt.*, pi_id from purchase t left join
|
|
|
|
|
+ // 2. union
|
|
|
|
|
+ // 这样的情况,很难区分,因此
|
|
|
|
|
+ // 1. 对于普通 sql ,将 select 后的字段改为 count(1)
|
|
|
|
|
+ // 2. 而最外层含有 group by 的 sql ,直接改为 count(1) 可能得到不止一行,结果也并非实际行数。再加上
|
|
|
|
|
+ // group by 的结果列数一般很小,所以可以在外面使用 count(1) ,一般不会超出 1000 行
|
|
|
|
|
+ // 3. union 外层使用 count(1)
|
|
|
|
|
+ if (!lowerSql.matches("[\\s\\S]+?group[\\s]+?by[\\s]+?[^)]+?")
|
|
|
|
|
+ && !lowerSql.matches("[\\s\\S]+?[\\s]+?union[\\s]+?[\\s\\S]+?")) {
|
|
|
|
|
+ String regex = "([\\s\\S]+?from)[\\s]+?[^,]+?";
|
|
|
|
|
+ Pattern pattern = Pattern.compile(regex);
|
|
|
|
|
+ Matcher matcher = pattern.matcher(lowerSql);
|
|
|
|
|
+ if (matcher.find()) {
|
|
|
|
|
+ int start = matcher.start(1);
|
|
|
|
|
+ int end = matcher.end(1);
|
|
|
|
|
+ sql = sql.substring(0, start) + "select count(1) from" + sql.substring(end);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ throw new IllegalStateException("sql 解析错误:未发现第一个 from");
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
- throw new IllegalStateException("sql 解析错误:未发现第一个 from");
|
|
|
|
|
|
|
+ sql = "select count(1) from (" + sql + ")";
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- sql = "select count(1) from (" + sql + ")";
|
|
|
|
|
|
|
+ throw new IllegalStateException("不支持的数据库类型:" + dbType);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
preparedStatement = connection.prepareStatement(sql);
|
|
preparedStatement = connection.prepareStatement(sql);
|
|
|
resultSet = preparedStatement.executeQuery();
|
|
resultSet = preparedStatement.executeQuery();
|
|
|
resultSet.next();
|
|
resultSet.next();
|