【Jdbc/Oracle】表结构克隆器 只要告诉它源表叫什么名,剩下的它包办

【功能】

以源表为基础,将其字段复刻下来制成新表。

【代码】

package com.hy.lab.clone;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据表克隆器
 * 将目标表尽量复刻下来做成新表
 */
public class TableCloner {
    //-- 以下为连接Oracle数据库的四大参数
    private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    private static final String USER = "luna";
    private static final String PSWD = "1234";

    public boolean duplicate(String srcTable,String destTable){
        Connection conn = null;
        PreparedStatement pstmt = null;

        try{
            Class.forName(DRIVER);
            conn = DriverManager.getConnection(URL, USER, PSWD);

            String createTableSql=getCreateSql(srcTable,destTable,conn);

            if(createTableSql!=null){
                // 建表
                pstmt = conn.prepareStatement(createTableSql);
                pstmt.execute();
                System.out.println(String.format("表%s已创建",destTable));

                return true;
            }else{
                return false;
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                pstmt.close();
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return false;
    }

    protected String getCreateSql(String srcTb,String destTb,Connection conn){
        PreparedStatement pstmt = null;

        try{
            String sql=String.format("select * from %s where 1=2",srcTb);
            pstmt = conn.prepareStatement(sql);
            // 核心语句,取得查询的元数据
            ResultSetMetaData rsmd=pstmt.executeQuery().getMetaData();

            // 方法内部类
            class Column{
                String name;
                String type;
                int length;
            }

            // 获得源表字段信息
            List<Column> fields=new ArrayList<>();
            for(int i=0;i<rsmd.getColumnCount();i++){
                int index=i+1;
                String columnName=rsmd.getColumnName(index);
                String columnType=rsmd.getColumnTypeName(index);
                int    columnSize=rsmd.getColumnDisplaySize(index);

                // 对于timestamp的特殊处理
                if(columnType.equalsIgnoreCase("timestamp")){
                    columnSize=9;
                }

                Column field = new Column();
                field.name = columnName;
                field.type = columnType;
                field.length = columnSize;
                fields.add(field);
            }

            // 组合创建语句
            StringBuilder sb=new StringBuilder();
            sb.append(String.format("create table %s(",destTb));
            List<String> ls=new ArrayList<>();
            for(Column field:fields){
                ls.add(String.format("   %s %s(%d)",field.name, field.type, field.length));
            }
            String columnBundle=String.join(",",ls);
            sb.append(columnBundle);
            sb.append(")");

            String createSql=sb.toString();
            System.out.println(String.format("建表语句=%s",createSql));

            // 返回建表语句
            return createSql;

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                pstmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    public static void main(String[] args){
        TableCloner tc=new TableCloner();
        tc.duplicate("test01","test01_clone");
    }
}

【复刻效果】

源表:

create table test01(
    id number(10),
    name varchar2(11),
    age number(3),
    remark nvarchar2(100),
    create_time timestamp,
    primary key(id)
)

复刻出的新表:

SQL> desc test01_clone;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER(11)
 NAME                                               VARCHAR2(11)
 AGE                                                NUMBER(4)
 REMARK                                             NVARCHAR2(100)
 CREATE_TIME                                        TIMESTAMP(9)

可以看出,复刻后,number字段都加了1的长度,varchar、nvarchar字段没有变长,timesatmp字段是人为设置的9,因为这个字段取不出真实长度。

基本完成了需求,各位可以根据自己需要修改。

END

posted @ 2022-03-23 14:24  逆火狂飙  阅读(39)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东