【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