JavaからJDBCでPostgreSQLのメタデータを取得
JavaからJDBCでPostgreSQLのメタデータを取得してみます。テーブル一覧とビュー一覧
テーブル一覧とビュー一覧は以下のSQLで取得できます。
select * from pg_tables
select * from pg_views
テーブル項目と主キー
テーブル項目は、メタデータのgetColumnsメソッドで取得し、主キーはメタデータのgetPrimaryKeysメソッドで取得します。 取得できる項目がこれが全てではありません。詳細はgetColumnsでググってください。
package posgre;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) throws Exception {
Connection conn = null;
try {
// クラスのロード
Class.forName("org.postgresql.Driver");
// コネクションの取得
conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/postgres", "postgres", "ps");
columns(conn);
keys(conn);
} finally {
if (conn != null) {
conn.close();
}
}
}
private static void columns(Connection conn) throws SQLException {
DatabaseMetaData dmd = conn.getMetaData();
String tableName = "test";
String schema = "public";
try (ResultSet rs = dmd.getColumns(null, schema, tableName, null)) {
while (rs.next()) {
System.out.println(rs.getString("COLUMN_NAME"));
System.out.println(rs.getString("TYPE_NAME"));
System.out.println(rs.getString("COLUMN_SIZE"));
}
}
}
private static void keys(Connection conn) throws SQLException {
DatabaseMetaData dmd = conn.getMetaData();
String tableName = "test";
String schema = "public";
try (ResultSet rs = dmd.getPrimaryKeys(null, schema, tableName)) {
while (rs.next()) {
System.out.println(rs.getString("COLUMN_NAME"));
System.out.println(rs.getString("PK_NAME"));
}
}
}
}
メタデータからDelete文とINSERT文を作成するサンプル
サンプルで書いてみましたが、万能ではありません。
package posgre;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class CreateTestData {
private static final String SCHEMA = "public";
private static final String OWNER = "postgres";
public static void main(String[] args) throws Exception {
Connection conn = null;
try {
// クラスのロード
Class.forName("org.postgresql.Driver");
// コネクションの取得
conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/postgres", "postgres", "ps");
CreateTestData createTestData = new CreateTestData();
createTestData.execute(conn);
} finally {
if (conn != null) {
conn.close();
}
}
}
private void execute(Connection conn) throws SQLException {
List<String> tableNames = getAllTableNames(conn);
for (String tableName : tableNames) {
TableData tableData = new TableData(conn, tableName);
CreateSQL createSQL = new CreateSQL(tableData);
if (createSQL.isPKeyExists()) {
output(createSQL.delete());
output(createSQL.insert());
} else {
output("主キーが未設定:" + tableName);
}
}
}
private void output(String str) {
System.out.println(str);
}
private List<String> getAllTableNames(Connection conn) throws SQLException {
ArrayList<String> ret = new ArrayList<>();
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
String sql = "select tablename from pg_tables where schemaname = '";
sql += SCHEMA;
sql += "' and tableowner = '";
sql += OWNER;
sql += "'";
rs = stmt.executeQuery(sql);
while (rs.next()) {
ret.add(rs.getString("tablename"));
}
} finally {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
}
return ret;
}
class TableData {
String tableName;
List<String> names = new ArrayList<>();
List<String> types = new ArrayList<>();
List<Integer> sizes = new ArrayList<>();
List<String> keys = new ArrayList<>();
public TableData(Connection conn, String tableName) throws SQLException {
this.tableName = tableName;
DatabaseMetaData dmd = conn.getMetaData();
extractKey(dmd);
extractCol(dmd);
}
private void extractKey(DatabaseMetaData dmd) throws SQLException {
try (ResultSet rs = dmd.getPrimaryKeys(null, SCHEMA, tableName)) {
while (rs.next()) {
keys.add(rs.getString("COLUMN_NAME"));
}
}
}
private void extractCol(DatabaseMetaData dmd) throws SQLException {
try (ResultSet rs = dmd.getColumns(null, SCHEMA, tableName, null)) {
while (rs.next()) {
names.add(rs.getString("COLUMN_NAME"));
types.add(rs.getString("TYPE_NAME"));
sizes.add(rs.getInt("COLUMN_SIZE"));
}
}
}
public String getTableName() {
return tableName;
}
public List<String> getNames() {
return names;
}
public List<String> getTypes() {
return types;
}
public List<String> getKeys() {
return keys;
}
public List<Integer> getSizes() {
return sizes;
}
}
class CreateSQL {
String tableName;
List<String> names;
List<String> keys;
Map<String, Column> mapCol = new HashMap<>();
public CreateSQL(TableData tableData) {
tableName = tableData.getTableName();
names = tableData.getNames();
keys = tableData.getKeys();
List<String> types = tableData.getTypes();
List<Integer> sizes = tableData.getSizes();
for (int i = 0; i < names.size(); i++) {
String name = names.get(i);
String type = types.get(i);
int size = sizes.get(i);
mapCol.put(name, new Column(name, type, size));
}
}
public boolean isPKeyExists() {
return keys.size() > 0;
}
public String delete() {
String where = keys.stream().map(key -> key + "=" + mapCol.get(key).val())
.collect(Collectors.joining(" AND "));
String sql = "DELETE FROM " + tableName;
sql += " WHERE ";
sql += where;
return sql;
}
public String insert() {
String cols = names.stream().collect(Collectors.joining(","));
String vals = names.stream().map(name -> mapCol.get(name).val()).collect(Collectors.joining(","));
String sql = "INSERT INTO " + tableName + "(";
sql += cols;
sql += ") VALUES(";
sql += vals;
sql += ")";
return sql;
}
}
class Column {
String value;
public Column(String name, String type, int size) {
Map<String, String> map = changeMap();
if (map.containsKey(name)) {
value = map.get(name);
return;
}
List<String> typeStrs = Arrays.asList("varchar", "bpchar", "text");
List<String> typeNums = Arrays.asList("int", "long", "float", "numeric", "numeric");
if (typeStrs.contains(type)) {
if (name.length() > size) {
value = "'" + name.substring(0, size) + "'";
} else {
value = "'" + name + "'";
}
return;
}
if (typeNums.stream().filter(typeNum -> type.startsWith(typeNum)).count() > 0) {
value = "" + name.length();
return;
}
if (type.startsWith("date")) {
value = "TO_DATE('2023/01/01', 'YYYY/MM/DD')";
return;
}
if (type.startsWith("timestamp")) {
value = "TO_TIMESTAMP('2023/01/01 11:22:33', 'YYYY/MM/DD HH24:MI:SS')";
return;
}
value = name;
}
public String val() {
return value;
}
private Map<String, String> changeMap() {
Map<String, String> ret = new HashMap<>();
return ret;
}
}
}
ページのトップへ戻る