使用jdbc獲取資料庫全部表、表包含欄位
阿新 • • 發佈:2018-12-09
1. 建立資料來源Vo, 封裝資料來源相關資訊;
//資料來源資訊 public class DataSource implements Serializable { //資料庫型別 private JdbcType jdbcType; //url private String jdbcUrl; //user private String jdbcUser; //pwd private String jdbcPassword; //表名 | 檢視名 private String tvname; //getter 、setter... }
2. 抽象出介面
public interface JdbcService { /** * 測試資料庫的連通性 * @return true表示成功 */ public boolean test(); /** * 列出所有的表和檢視 * @return 所有的表和檢視 */ public List<String> listAllTables(); /** * 列出所有包含某些欄位的表和檢視 * @param fields 欄位 * @return 所有包含某些欄位的表和檢視 */ public List<String> listAllTablesFields(String... fields); /** * 列出所有的欄位 * @param tableName表名或檢視名 * @return 所有的欄位 */ public List<String> listAllFields(String tableName); }
3. 介面抽象實現類
public abstract class AbstractJdbcService implements JdbcService { private final DataSource dataSource; public AbstractJdbcService(DataSource dataSource) { this.dataSource = dataSource; checkDataSource(dataSource); } /** * 校驗資料來源資訊是否有效 * @param dataSource 資料來源 */ private void checkDataSource(DataSource dataSource){ if(dataSource == null){ throw new IllegalArgumentException("dataSource is null. "); } if(StringUtils.isBlank(dataSource.getJdbcUrl())){ throw new IllegalStateException("jdbc url is null. "); } if(StringUtils.isAnyBlank(dataSource.getJdbcUser(), dataSource.getJdbcPassword())){ throw new IllegalStateException("jdbc user or password is null. "); } } protected DataSource getDataSource() { return dataSource; } /** * 關閉(釋放)資源 * @param conn Connection */ protected void close(Connection conn){ close(conn, null, null); } /** * 關閉(釋放)資源 * @param conn Connection * @param ps PreparedStatement * @param rs ResultSet */ protected void close(Connection conn, Statement ps, ResultSet rs){ //關閉ResultSet if(rs != null){ try { rs.close(); } catch (SQLException e) { rs = null; } } //關閉PreparedStatement if(ps != null){ try { ps.close(); } catch (SQLException e) { ps = null; } } //關閉Connection if(conn != null){ try { conn.close(); } catch (SQLException e) { conn = null; } } } @Override public boolean test() { Connection conn = null; try { conn = getConnection(); if(conn == null){ return false; } DatabaseMetaData meta = conn.getMetaData(); if(meta == null){ return false; } } catch (SQLException e) { } finally { close(conn); } return true; } /** * 獲取連線 * @return Connection */ protected Connection getConnection(){ Connection conn = null; try { Class.forName(loadDriverClass()); conn = DriverManager.getConnection(dataSource.getJdbcUrl(), dataSource.getJdbcUser(), dataSource.getJdbcPassword()); } catch (Exception e) { } return conn; } @Override public List<String> listAllTables() { Connection conn = getConnection(); if(conn == null){ return null; } List<String> result = new ArrayList<>(); ResultSet rs = null; try{ //引數1 int resultSetType //ResultSet.TYPE_FORWORD_ONLY 結果集的遊標只能向下滾動。 //ResultSet.TYPE_SCROLL_INSENSITIVE 結果集的遊標可以上下移動,當資料庫變化時,當前結果集不變。 //ResultSet.TYPE_SCROLL_SENSITIVE 返回可滾動的結果集,當資料庫變化時,當前結果集同步改變。 //引數2 int resultSetConcurrency //ResultSet.CONCUR_READ_ONLY 不能用結果集更新資料庫中的表。 //ResultSet.CONCUR_UPDATETABLE 能用結果集更新資料庫中的表 conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); DatabaseMetaData meta = conn.getMetaData(); //目錄名稱; 資料庫名; 表名稱; 表型別; rs = meta.getTables(catalog(), schemaPattern(), tableNamePattern(), types()); while(rs.next()){ result.add(rs.getString("TABLE_NAME")); } }catch(Exception e){ e.printStackTrace(); }finally { close(conn, null, rs); } return result; } @Override public List<String> listAllFields(String tableName) { Connection conn = getConnection(); if(conn == null){ return null; } List<String> result = new ArrayList<>(); ResultSet rs = null; try{ DatabaseMetaData meta = conn.getMetaData(); rs = meta.getColumns(catalog(), schemaPattern(), tableOrViewName.trim(), null); while(rs.next()){ result.add(rs.getString("COLUMN_NAME")); } }catch(Exception e){ }finally{ close(conn, null, rs); } return result; } @Override public List<String> listAllTablesFields(String... fields) { //如果欄位為空, 則返回null if(fields == null || fields.length == 0){ return null; } //如果表結構(檢視)為空, 則返回null List<String> tvs = listAllTables(); if(tvs == null || tvs.size() == 0){ return null; } List<String> result = new CopyOnWriteArrayList<>(); //併發篩選包含特定欄位的表結構 tvs.parallelStream().forEach(tv -> { List<String> fieldsList = listAllFields(tv); if(fieldsList != null && fieldsList.size() > 0){ if(fieldsList.containsAll(Arrays.asList(fields))){ result.add(tv); } } }); return result; } /** * a catalog name; must match the catalog name as it is stored in the database; "" retrieves those without a catalog; null means that the catalog name should not be used to narrow the search */ protected String catalog(){ return null; } /** * a table name pattern; must match the table name as it is stored in the database */ protected String tableNamePattern(){ return "%"; } /** * a list of table types, which must be from the list of table types returned from {@link DatabaseMetaData.getTableTypes},to include; null returns all types */ protected String[] types(){ return new String[]{"TABLE", "VIEW"}; } /** * 載入驅動class * @return class */ protected abstract String loadDriverClass(); /** * a schema name pattern; must match the schema name as it is stored in the database; "" retrieves those without a schema; null means that the schema name should not be used to narrow the search */ protected abstract String schemaPattern(); }
4. 工廠類
public class JdbcServiceFactory {
/**
* 獲取jdbc service
* @param dataSource 資料來源
* @return jdbc service
*/
public static JdbcService getJdbcService(DataSource dataSource){
if(dataSource.getJdbcType() == JdbcType.MYSQL){
return new MySQLJdbcService(dataSource);
}else if(dataSource.getJdbcType() == JdbcType.ORACLE){
return new OracleJdbcService(dataSource);
}
return null;
}
}
5. mysql對應jdbc實現
public class MySQLJdbcService extends AbstractJdbcService {
public MySQLJdbcService(DataSource dataSource) {
super(dataSource);
}
@Override
protected String loadDriverClass() {
return "com.mysql.jdbc.Driver";
}
@Override
protected String schemaPattern() {
//mysql的schemaPattern為資料庫名稱
String url = getDataSource().getJdbcUrl();
//jdbc:mysql://localhost:3306/iso_db?useUnicode=true&characterEncoding=UTF-8
String database = url.substring(url.indexOf("/", 13) + 1);
int index = database.indexOf("?");
if(index > 0){
database = database.substring(0, index);
}
return database;
}
}
6. oracle對應jdbc實現
public class OracleJdbcService extends AbstractJdbcService {
public OracleJdbcService(DataSource dataSource) {
super(dataSource);
}
@Override
protected String loadDriverClass() {
return "oracle.jdbc.driver.OracleDriver";
}
/**
* 注意:oracle使用者名稱稱須大寫
*/
@Override
protected String schemaPattern() {
//oracle的schemaPattern為使用者名稱
return getDataSource().getJdbcUser().toUpperCase();
}
}