Java ,druid1.2.8 解析sql,并通过 feign接口查询到的表元数据,替换包含left join 的select sql语句中的*,支持mysql、hive、postgresql、oracle、sqlserver等多种数据库
时间: 2023-07-16 10:13:55 浏览: 56
这个需求可以通过以下步骤实现:
1. 使用Druid解析SQL,获取SQL语句中的表名和字段名。
2. 使用Feign调用元数据服务,获取表的元数据信息,包括表的字段名、类型等。
3. 解析SQL语句,找到包含LEFT JOIN的SELECT语句,并将其中的*替换为具体的字段名。
4. 根据不同的数据库类型,生成对应的SQL语句。
下面是一个大致的实现过程:
```java
// 1. 使用Druid解析SQL,获取SQL语句中的表名和字段名
String sql = "SELECT t1.*, t2.name FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id";
List<SQLTableSource> tableSources = SQLUtils.getTables(sql, JdbcConstants.MYSQL);
List<SQLSelectItem> selectItems = SQLUtils.getSelectItems(sql, JdbcConstants.MYSQL);
// 2. 使用Feign调用元数据服务,获取表的元数据信息
TableMetadata metadata = metadataService.getTableMetadata(tableSources.get(0).getName());
// 3. 解析SQL语句,找到包含LEFT JOIN的SELECT语句,并将其中的*替换为具体的字段名
for (SQLSelectItem item : selectItems) {
if (item.getExpr() instanceof SQLAllColumnExpr) {
SQLAllColumnExpr allColumnExpr = (SQLAllColumnExpr) item.getExpr();
if (allColumnExpr.getOwner() instanceof SQLIdentifierExpr) {
String tableName = ((SQLIdentifierExpr) allColumnExpr.getOwner()).getName();
if ("t1".equals(tableName)) {
List<String> columnNames = metadata.getColumnNames(tableName);
SQLSelectItem newItem = new SQLSelectItem();
newItem.setExpr(new SQLIdentifierExpr(columnNames.get(0)));
item.getParent().set(item.getParent().indexOf(item), newItem);
}
}
}
}
// 4. 根据不同的数据库类型,生成对应的SQL语句
String newSql = SQLUtils.toSQLString(stmt, JdbcConstants.MYSQL);
```
需要注意的是,这只是一个简单的示例代码,实际应用中还需要处理很多细节问题,比如SQL语句中可能包含多个表,需要进行关联查询,还需要处理各种可能出现的异常情况。