本文主要是介绍Druid连接池工具公式化SQL附踩坑记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1. 需求
使用Druid连接池工具格式化sql用于回显时候美观展示
2. 代码示例
2.1 依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version>
</dependency>
2.2 ParseUtils
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGOutputVisitor;
import com.alibaba.druid.sql.parser.SQLParserUtils;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.alibaba.druid.sql.visitor.SQLASTOutputVisitor;import java.util.List;/*** @author pp_lan* @date 2024/1/15*/
public class ParseUtils {private ParseUtils() {}public static String format(String sql, String dbTypeStr) {DbType dbType = DbType.of(dbTypeStr);if (dbType == null) {throw new RuntimeException("不支持的数据库类型");}List<SQLStatement> statementList = toStatementList(sql, dbType);String result = sqlToString(statementList, dbTypeStr, null);return result;}public static List<SQLStatement> toStatementList(String sql, DbType dbType) {SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);return parser.parseStatementList();}public static String sqlToString(List<SQLStatement> statementList, String dbType, List<Object> parameters) {StringBuilder sb = new StringBuilder();SQLASTOutputVisitor visitor;switch (dbType) {case "postgresql":visitor = new PGOutputVisitor(sb);break;case "mysql":visitor = new MySqlOutputVisitor(sb);break;default:visitor = new SQLASTOutputVisitor(sb);}visitor.setParameters(parameters);for (SQLStatement statement : statementList) {statement.accept(visitor);}return sb.toString();}public static void main(String[] args) {// 使用::将数值转为varchartry {System.out.println("[使用::转换]");String sql = "select sum(in_use) :: varchar from t_user";System.out.println(format(sql, DbType.postgresql.name()));} catch (Exception e) {System.out.println("使用::转换异常");}// 使用cast将数值转为varchartry {System.out.println("[使用cast转换]");String newSql = "select cast(sum(in_use) as varchar) from t_user";System.out.println(format(newSql, DbType.postgresql.name()));} catch (Exception e) {System.out.println("使用cast转换异常");}}}
3. 运行结果
[使用::转换]
SELECT sum(in_use)::varchar
FROM t_user
[使用cast转换]
SELECT CAST(sum(in_use) AS varchar)
FROM t_user
4. 踩坑记录
4.1 描述
之前我使用的是druid为1.2.4版本,在解析pg库sql时候,发现执行结果如下:
[使用::转换]
使用::转换异常
[使用cast转换]
SELECT CAST(sum(in_use) AS varchar)
FROM t_user
可以发现,转换函数::在解析时候异常了
4.2 解决方法
切换高版本1.2.6及以上,可以正常解析。
4.3 总结
druid的1.2.6以下版本对于包含数值使用::转换为varchar的场景不支持,会导致解析报错。可以使用以下方法解决:
- 升级druid版本到1.2.6及以上
- 在格式化的方法上加上try-catch,格式化异常的时候使用原来的sql用于回显
这篇关于Druid连接池工具公式化SQL附踩坑记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!