在使用sharding插件时,有时我们需要动态获取指定表的字段,类型等数据结构。但是在直接使用sql语句查询时sharding插件会将查询sql 转换错误。此时我们该怎么办呢。
思路:
第一步 :获取shardind数据源
第二步:获取数据库链接信息
第三补:重建数据源链接
第四部: 关闭链接
不废话直接上代码:
/**
* Sharding 分库分表需要这个来查询
* @param SqlDbDataVo
* @return
*/
private List<SqlColumnData> getColumns(SqlDbDataVo SqlDbDataVo){
Connection con =null;
ResultSet rs =null;
Connection connection =null;
List<SqlColumnData> data = new ArrayList<>();
try {
// 获取该服务链接的sharding数据源
ShardingDataSource shardingDataSource = (ShardingDataSource) ApplicationContextConfig.getBean("dataSource");
if(shardingDataSource == null) return null;
connection = shardingDataSource.getConnection();
if(connection == null) return null;
// 获取多数据源
Map<String, DataSource> dataA = shardingDataSource.getDataSourceMap();
// 轮询获取指定目标库表 这里测试直接全部轮询了
for(String key : dataA.keySet()){
DruidDataSource d = (DruidDataSource) dataA.get(key);
Class.forName(d.getDriverClassName());
con = DriverManager.getConnection(d.getUrl(), d.getUsername(), d.getPassword());
if(!con.isClosed()) {//判断数据库是否链接成功
//3、创建Statement对象
Statement st = con.createStatement();
//4、执行sql语句
StringBuffer sql = new StringBuffer(" SELECT COLUMN_NAME, DATA_TYPE,COLUMN_COMMENT FROM information_schema.Columns WHERE table_schema = '"+SqlDbDataVo.getTableSchema()+"'");
sql.append(" AND TABLE_NAME ='"+SqlDbDataVo.getTableName()+"' ");
if(SqlDbDataVo.getType() == 1 ){
sql.append(" AND DATA_TYPE !='datetime' AND COLUMN_NAME !='deleted'");
}
if(SqlDbDataVo.getType() == 2 ){
sql.append(" AND DATA_TYPE ='datetime' ");
}
sql.append(" AND COLUMN_NAME != '"+SqlDbDataVo.getFiled()+"'");
try {
rs = st.executeQuery(sql.toString());//查询之后返回结果集
//5、打印出结果
while (rs.next()) {
data.add(new SqlColumnData(rs.getString("COLUMN_NAME"), rs.getString("DATA_TYPE"), rs.getString("COLUMN_COMMENT")));
}
}catch (Exception e){
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (rs != null) rs.close();//关闭资源
if (con != null) con.close();//关闭数据库
if (connection != null) connection.close();//关闭数据库
}catch (Exception e){
e.printStackTrace();
}
}
return data;
}
@Data
public class SqlColumnData {
@TableField("COLUMN_NAME")
private String columnName;
@TableField("DATA_TYPE")
private String dataType;
@TableField("COLUMN_COMMENT")
private String columnComment;
public SqlColumnData() {
}
public SqlColumnData(String columnName, String dataType, String columnComment) {
this.columnName = columnName;
this.dataType = dataType;
this.columnComment = columnComment;
}
}