Browse Source

modify the query according dbType when getCount

sunyj 8 years ago
parent
commit
9a2bedcd76
1 changed files with 36 additions and 27 deletions
  1. 36 27
      src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

+ 36 - 27
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -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();