PostgreSQL采用Java导出表结构
前言
PostgreSQL采用Java导出表结构,包含删除已存在的表,创建表结构,添加主键索引,表备注,字段备注。
一、获取表名和表备注
注意:obj_description(pc.oid) 获取表备注,order为schema的名称
字段 | 说明 |
---|---|
table_schema | schema |
table_name | 表名 |
obj_description(pc.oid) | 表名备注 |
SQL查询实现
select distinct c.table_schema, c.table_name,
obj_description(pc.oid) as table_comment
from information_schema.columns c
join pg_catalog.pg_class pc
on c.table_name = pc.relname
where c.table_schema = 'order';/**schema名称*/
二、获取表结构
注意:只需要传入shcema和table_name即可获取表结构
字段 | 说明 |
---|---|
column_name | 字段名称 |
udt_name | 字段类型 |
c.character_maximum_length | varchar的长度 |
numeric_precision | numeric的最大长度 |
nummeric_scale | numeric的小数位数 |
select c.column_name, c.udt_name,
c.character_maximum_length as c_l, c.is_nullable,
c.numeric_precision, c.nummeric_scale
from information_schema.columns c
where c.table_schema = 'order' and c.table_name = 'shopping_car'
order by ordinal_position;
三、获取唯一键
字段 | 说明 |
---|---|
constraint_name | 唯一键名称 |
column_key | 唯一键字段合集 |
select c.constraint_name, string_agg(c.column_name, ',' order by ordinal_position) as column_key
from information_schema.key_column_usage c
where c.table_schema = 'order' and c.table_name = 'shopping_car'
group by ordinal_position
四、获取字段备注
字段 | 说明 |
---|---|
column_name | 字段名称 |
column_comment | 字段备注 |
select c.attname as column_name, col_description(c.attrelid,c.attnum) as column_comment
from pg_catalog.pg_attribute c
where c.attrelid = 'order.shopping_car'::regclass and c.attnum > 0
五、Java代码实现导出表结构
public class Run {
@Autowired
private JdbcTemplate jdbcTemplate;
public void run() {
List<Map<String, Object>> tables = tables("test");
for (Map<String, Object> map : tables) {
createTable(mapString(map, "table_schema"), mapString(map, "table_name"), mapString(map, "table_comment"));
}
}
/**
* 写入文件
*/
public void runWriteFile() {
String path = "table.sql";
List<Map<String, Object>> tables = tables("test");
try (FileWriter fw = new FileWriter(path)) {
for (Map<String, Object> map : tables) {
String table = createTable(mapString(map, "table_schema"), mapString(map, "table_name"), mapString(map, "table_comment"));
fw.write(table);
}
fw.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取Map中的值,并转换为String格式
*/
public String mapString(Map<String, Object> map, String key) {
return String.valueOf(map.get(key));
}
/**
* 根据schema,获取所有的表名对应的备注
*
* @param tableSchema schema
*/
public List<Map<String, Object>> tables(String tableSchema) {
return jdbcTemplate.queryForList(
"select distinct c.table_schema, c.table_name, obj_description(pc.oid) as table_comment \n" +
"from information_schema.columns c \n" +
"join pg_catalog.pg_class pc \n" +
" on c.table_name = pc.relname \n" +
"where c.table_schema = '" + tableSchema + "'"
);
}
/**
* 根据schema和表名,获取字段名称、字段类型、varchar长度、是否为空、numeric长度、numeric小数位数
*
* @param tableSchema schema
* @param tableName 表名
*/
public List<Map<String, Object>> tableColumns(String tableSchema, String tableName) {
return jdbcTemplate.queryForList(
"select c.column_name, c.udt_name, c.character_maxinum_length as cl, \n" +
"c.is_nullable, c.numeric_precision, c.numeric_scale \n" +
"from information_schema.columns c \n" +
"where c.table_schema = '" + tableSchema + "' and c.table_name = '" + tableName + "'\n" +
"order by ordinal_position");
}
/**
* 根据schema和表名,获取主键
*
* @param tableSchema schema
* @param tableName 表名
*/
public List<Map<String, Object>> tableKeys(String tableSchema, String tableName) {
return jdbcTemplate.queryForList(
"select c.constraint_name, string_agg(c.column_name, ',' order by ordinal_position) as column_key \n" +
"from information_schema.key_column_usage c \n" +
"where c.table_schema = '" + tableSchema + "' and c.table_name = '" + tableName + "'\n" +
"group by ordinal_position");
}
/**
* 根据全名(schema+表名),获取表字段和对应的备注
*
* @param fullTable 全名
*/
public List<Map<String, Object>> columnComments(String fullTable) {
return jdbcTemplate.queryForList(
"select c.attname as column_name, col_description(c.attrelid,c.attnum) as column_comment \n" +
"from pg_catalog.pg_attribute c \n" +
"where c.attrelid = '" + fullTable + "'::regclass and c.attnum > 0 ");
}
public String createTable(String tableSchema, String tableName, String tableComment) {
StringBuilder sb = new StringBuilder();
String fullTable = tableSchema + "." + tableName;
//删除表
sb.append("DROP TABLE IF EXISTS ").append(fullTable).append(";\r\n");
//创建表
sb.append("CREATE TABLE ").append(fullTable).append("(\r\n");
List<Map<String, Object>> tableColumns = tableColumns(tableSchema, tableName);
for (Map<String, Object> map : tableColumns) {
sb.append(" ").append(mapString(map, "column_name")).append(" ");
//字段类型
String type = mapString(map, "udt_name");
sb.append(type);
if ("varchar".equals(type)) {
sb.append("(").append(map.get("c_l")).append(")");
} else if ("numeric".equals(type)) {
sb.append("(").append(map.get("numeric_precision")).append(",").append(map.get("numeric_scale")).append(")");
}
//是否为空
String isNull = mapString(map, "is_nullable");
if ("NO".equals(isNull)) {
sb.append(" NOT NULL,\r\n");
} else {
sb.append(" NULL,\r\n");
}
}
//唯一键
List<Map<String, Object>> tableKeys = tableKeys(tableSchema, tableName);
for (Map<String, Object> map : tableKeys) {
sb.append(" CONSTRAINT ").append(map.get("constraint_name"))
.append(" PRIMARY KEY (").append(map.get("column_key")).append(")\r\n");
}
//如果为空,需要删除掉一个,
if (tableKeys.isEmpty()) {
sb.delete(sb.length() - 3, sb.length());
sb.append("\r\n");
}
sb.append(");\r\n");
//添加表备注
if (tableComment != null && !"null".equals(tableComment)) {
sb.append("comment on table ").append(fullTable).append(" is '")
.append(tableComment).append("';\r\n");
}
//添加字段备注
List<Map<String, Object>> columnComments = columnComments(fullTable);
for (Map<String, Object> map : columnComments) {
String comment = mapString(map, "column_comment");
if (comment != null && !"null".equals(comment)) {
sb.append("comment on column ").append(fullTable).append(".")
.append(map.get("column_name")).append(" is '")
.append(tableComment).append("';\r\n");
}
}
System.out.println(sb);
return sb.toString();
}
}