利用DataBaseMetaData和ResultSetMetaData复制数据库的表和数据

时间:2022-09-28 12:02:08

测试代码见我的云盘“学习路径/自己做的例子/CopyDatabase”


我们有时候可能需要复制一个数据库中的数据,可能同一个数据库中操作还简单,但是跨数据库的操作就可能很麻烦了,常见的工具都做不到。

现利用DataBaseMetaData和ResultSetMetaData实现了一个功能,生成数据库中的表的所有数据的insert语句,你只需要在你的数据库中运行这个代码即可。

操作步骤是:1.在你的数据库中创建你需要复制的表  2.运行代码生成的insert语句

SqlHelper.java【获取Connection和查询功能】

public class SqlHelper {

    Connection ct=null;
    PreparedStatement ps=null;
    ResultSet rs=null;
    String driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver";
    String url="jdbc:sqlserver://localhost:1433; DatabaseName=InstrumentManager";
    String user="sa";
    String password="xsy881026";

//    String driverName="com.mysql.jdbc.Driver";
//    String url="jdbc:mysql://localhost:3306/InstrumentManager";
//    String user="root";
//    String password="root";

    
    public SqlHelper(){
        try {
            Class.forName(driverName);
            ct=DriverManager.getConnection(url,user,password);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }    
    public ResultSet query(String sql,String ...args){
        try {
            ps=ct.prepareStatement(sql);
            for(int i=0;i<args.length;i++)
                ps.setString(i+1, args[i]);
            rs=ps.executeQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rs;
    }

    public Connection getConnection(){
        return ct;
    }

    //把数据库的增,删,改 写一个函数
    public boolean exeUpdate(String sql, Object ...args)
    {
        boolean b=true;
        try {
            ps=ct.prepareStatement(sql);
            //给sql语句中的?号赋值
            for(int i=0; i<args.length; i++)
            {
                ps.setObject(i+1,args[i]);
            }
            ps.executeUpdate();   //更新数据
        } catch (Exception e) {
            // TODO: handle exception
            b=false;
            e.printStackTrace();
        }
        return b;
    }
    public void close(){
            try {
                if(rs!=null)
                    rs.close();
                if(ps!=null)
                    ps.close();
                if(ct!=null)
                    ct.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
}


public class GenerateSQL {
    @Test
    public void testGenerateSQL(){
        SqlHelper helper = new SqlHelper();
        String[] tableNames = {"table_bwpv","table_department","table_employee","table_forum",
                "table_gama","table_gotowell","table_inouthistory","table_instrumentbaseinfo",
                "table_instrumentcycling","Table_MaintainanceOfComponent","Table_MaintainanceOfInstruement",
                "Table_MWD","Table_Node","Table_NodeCascade","Table_Resistivity","Table_Stock","Table_WellInfo"};
        try {
            System.out.println(helper.getConnection().getCatalog());//获取数据库名称
            //获取所有的数据表
            ResultSet set = helper.getConnection().getMetaData().getTables(null, null, null, new String[]{"TABLE"});
            while (set.next()) {
                String tableName = set.getString(3);
                //根据表获取数据
                createInsertSQL(helper, tableName);
            }
            set.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    /**
     * 根据表名复制表中的数据,生成insert语句,
     * 目前只能支持数字型和字符型的数据,对于
     * 二进制的数据,需要特殊的处理方式

     * @param helper
     * @param tableName
     */
    private void createInsertSQL(SqlHelper helper, String tableName) {
        try {
            ResultSet set = helper.query(
                    "select * from "+tableName);
            ResultSetMetaData metaData = set.getMetaData();
            int count = metaData.getColumnCount();
            //List<String>  labels = getLabels(metaData);

            OutputStream os = new FileOutputStream("copy.sql");

            StringBuffer insertSQL = null;
            while (set.next()) {
                insertSQL = new StringBuffer("INSERT INTO " + tableName + " VALUES(");
                for (int i = 0; i < count; i++) {
                    Object obj = set.getObject(i+1);
                    int type = metaData.getColumnType(i+1);
                    if(isChar(type)){//根据列的类型看是否需要添加''
                        insertSQL.append("'"+obj+"'").append(",");
                    }else{
                        insertSQL.append(obj).append(",");
                    }
                }
                String sql = insertSQL.substring(0, insertSQL.length()-1);//去掉最后的逗号
                sql= sql +")";
                System.out.println(sql);//这个语句可以保存到文件中,在你的数据库中运行这个文件即可。

                 os.write(sql.getBytes());
            }
            set.close();

           os.close();           
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private boolean isChar(int type) {
        switch (type) {
        case Types.CHAR:
        case Types.DATE:
        case Types.LONGNVARCHAR:
        case Types.LONGVARCHAR:
        case Types.NCHAR:
        case Types.NVARCHAR:
        case Types.SQLXML:
        case Types.VARCHAR:
        case Types.TIMESTAMP:
        case Types.TIME:
            return true;
        default :
            return false;
        }
    }
    private List<String> getLabels(ResultSetMetaData metaData) throws SQLException {
        String label;
        List<String> labels = new ArrayList<String>();
        int count = metaData.getColumnCount();
        for (int i = 0; i < count; i++) {
            label = metaData.getColumnLabel(i+1);
            //System.out.println(label);
            int type = metaData.getColumnType(i+1);
            System.out.println(type);
            //Types
            labels.add(label);
        }
        return labels;
    }
}


生成的测试语句

想想如果我们手动敲的话多占用时间和精力。

InstrumentManager
INSERT INTO Table_Department VALUES(1,'仪器检修中心',20,'负责仪器检修,厂房管理')
INSERT INTO Table_Department VALUES(2,'仪器现场技术推广中心',40,'负责仪器上井工作,管理')
INSERT INTO Table_Department VALUES(3,'随钻测量与控制技术研究所',30,'负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发,负责仪器研发')