PostgreSQL采用Java导出表结构

PostgreSQL采用Java导出表结构


前言

PostgreSQL采用Java导出表结构,包含删除已存在的表,创建表结构,添加主键索引,表备注,字段备注。

一、获取表名和表备注

注意:obj_description(pc.oid) 获取表备注,order为schema的名称

字段说明
table_schemaschema
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_lengthvarchar的长度
numeric_precisionnumeric的最大长度
nummeric_scalenumeric的小数位数
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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值