有没有什么更好的实现办法?Java对比两个数据库的内容

问题描述

目前所在的项目组距离下个版本上线已经很近了,就面临了一个问题:开发人员在开发库上根据需要增加数据表、数据字段、或者变更了字段类型或者字段长度等等。由于时间比较紧迫,导致在开发过程中不可能一一把DDL数据库脚本记录下来,在比较大的项目中,比如我所在项目开发的系统大概包含了800张左右的表,字段上10000个的情况下,人工处理明显不可行,所以我们就得通过程序来判断比对,哪些是我们需要新增加的表,哪些是我们需要新增加的字段,哪些是我们需要修改的字段。首先是一个Table类,代表了我们数据库中的一张表,其中存在String类型的表名、和存放若干个各种字段的HashMap<String,Column>()packagetest;importjava.util.HashMap;publicclassTable{publicStringtableName;publicHashMapcolumns=newHashMap();publicTable(StringtableName){this.tableName=tableName;}publicStringgetTableName(){returntableName;}publicvoidsetTableName(StringtableName){this.tableName=tableName;}publicHashMapgetColumns(){returncolumns;}publicvoidsetColumns(HashMapcolumns){this.columns=columns;}}

接着就是一个Column类,代表了数据库中的一个字段,其中属性就是字段名、字段类型、字段长度,当然可以根据自己的需求加入更多要素packagetest;publicclassColumn{publicStringcolumnName;publicStringdataType;publicintlength;publicColumn(StringcolumnName,StringdataType,intlength){this.columnName=columnName;this.dataType=dataType;this.length=length;}publicStringgetColumnName(){returncolumnName;}publicvoidsetColumnName(StringcolumnName){this.columnName=columnName;}publicStringgetDataType(){returndataType;}publicvoidsetDataType(StringdataType){this.dataType=dataType;}publicintgetLength(){returnlength;}publicvoidsetLength(intlength){this.length=length;}}

其实这个方法完全可以不用上面两个类的,但是为了写起来理解方便,所以就用了,执行效率其实还不错,几百张表几秒钟就跑完了下面是实现这个需求的主要类,写出来的主要目的就是希望能帮我改进一下,毕竟自己写程序没有太多的设计理念和大局观,希望能者修改修改:packagetest;packagetest;importjava.io.File;importjava.io.FileOutputStream;importjava.io.OutputStream;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.util.HashMap;importjava.util.Iterator;importjava.util.Map;importcom.amarsoft.are.sql.ASResultSet;importcom.amarsoft.are.sql.Transaction;importcom.amarsoft.are.util.DataConvert;publicclassCompareTable{publicstaticStringBuffer[]sb={newStringBuffer(),newStringBuffer(),newStringBuffer(),newStringBuffer(),newStringBuffer(),newStringBuffer()};publicstaticTransactiongetTransaction_product()throwsException{Class.forName("oracle.jdbc.driver.OracleDriver");Connectionconn=DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.1:1621:orcl","demo1","demo1");if(conn!=null)System.out.println("数据库加载成功!");Transactiontransaction=newTransaction(conn);returntransaction;}publicstaticTransactiongetTransaction_develop()throwsException{Class.forName("oracle.jdbc.driver.OracleDriver");Connectionconn=DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.2:1621:orcl","demo2","demo2");if(conn!=null)System.out.println("数据库加载成功!");Transactiontransaction=newTransaction(conn);returntransaction;}publicstaticvoidmain(String[]args)throwsException{compareTables();//比较数据库writeFile();//写入文件}/***@authorYUJIYU090比较生产库和开发库的数据表,包括表名、字段名、字段类型、字段长度**/publicstaticvoidcompareTables()throwsException{//生产数据库连接Transactiontrans_product=getTransaction_product();Map<String,Table>map_product=getTables(trans_product);//开发数据库连接Transactiontrans_develop=getTransaction_develop();Map<String,Table>map_develop=getTables(trans_develop);//遍历开发库Mapfor(Iterator<String>iter_table=map_develop.keySet().iterator();iter_table.hasNext();){Stringkey_table=(String)iter_table.next();Tabletable_develop=map_develop.get(key_table);//获得开发库中的表Tabletable_product=map_product.get(key_table);//尝试从生产库中获得同名表if(table_product==null){//如果获得表为空,说明开发存在,生产不存在append(table_develop,null,2);}else{//表相同,判断字段、字段类型、字段长度for(Iterator<String>iter_column=table_develop.columns.keySet().iterator();iter_column.hasNext();){Stringkey_column=(String)iter_column.next();Columncolumn_develop=table_develop.columns.get(key_column);//获得开发库中的列Columncolumn_product=table_product.columns.get(key_column);//尝试从生产库中获得同名列if(column_product==null){//如果列名为空,说明开发存在,生产不存在append(table_develop,column_develop,4);}else{//说明两者都存在if(!column_develop.dataType.equals(column_product.dataType))//字段类型不一致append(table_develop,column_develop,5);if(column_develop.length!=column_product.length)//字段长度不一致append(table_develop,column_develop,6);}}}}//遍历生产库Mapfor(Iterator<String>iter_table=map_product.keySet().iterator();iter_table.hasNext();){Stringkey_table=(String)iter_table.next();Tabletable_product=map_product.get(key_table);//尝试从生产库中获得同名表Tabletable_develop=map_develop.get(key_table);//获得开发库中的表if(table_develop==null){//如果获得表为空,说明开发存在,生产不存在append(table_product,null,1);}else{//表相同,判断字段、字段类型、字段长度for(Iterator<String>iter_column=table_product.columns.keySet().iterator();iter_column.hasNext();){Stringkey_column=(String)iter_column.next();Columncolumn_product=table_product.columns.get(key_column);//获得生产库中的列Columncolumn_develop=table_develop.columns.get(key_column);//尝试从开发库中获得同名列if(column_develop==null){//如果列名为空,说明生产存在,开发不存在append(table_product,column_product,3);}}}}}/***@authorYUJIYU090传入数据库连接,返回数据库中所有TABLE对象的MAP**/publicstaticMap<String,Table>getTables(Transactiontransaction)throwsException{StringsSql="selecttable_name,Column_Name,Data_Type,"+"DECODE(DATA_TYPE,'NUMBER',DATA_PRECISION,'VARCHAR2',"+"DATA_LENGTH,'VARCHAR',DATA_LENGTH,'CHAR',DATA_LENGTH,0)Length,"+"NVL(DATA_SCALE,0)SCALE,DECODE(NULLABLE,'N','1','0')NULLABLE"+"fromuser_tab_columnswhere1=1OrderBytable_name,column_name";ASResultSetrs=transaction.getASResultSet(sSql);Map<String,Table>map=newHashMap<String,Table>();StringtableName="";Tabletable=null;while(rs.next()){if(!tableName.equals(rs.getString("table_name"))){//一张新表tableName=rs.getString("table_name");table=newTable(tableName);Columncolumn=newColumn(rs.getString("Column_Name"),rs.getString("Data_Type"),rs.getInt("Length"));table.columns.put(column.columnName,column);map.put(rs.getString("table_name"),table);}else{//已存在的表,增加字段Columncolumn=newColumn(rs.getString("Column_Name"),rs.getString("Data_Type"),rs.getInt("Length"));table.columns.put(column.columnName,column);}}if(null!=rs)rs.close();transaction.finalize();returnmap;}/***@authorYUJIYU090根据标示位,追加到满足条件的StringBuffer**/publicstaticvoidappend(Tabletable,Columncolumn,intflag)throwsException{switch(flag){case1:System.out.println("1、生产存在,开发不存在的表:"+table.getTableName());//跳过sb[0].append(table.getTableName()+"n");break;case2:System.out.println("2、生产不存在,开发存在的表:"+table.getTableName());//需要人工判断脚本sb[1].append(table.getTableName()+"n");break;case3:System.out.println("3、生产存在,开发不存在的字段:"+table.getTableName()+"|"+column.getColumnName());//需人工判断如何处理sb[2].append(table.getTableName()+"|"+column.getColumnName()+"n");break;case4:System.out.println("4、生产不存在,开发存在的字段:"+table.getTableName()+"|"+column.getColumnName());//需要人工判断脚本sb[3].append(table.getTableName()+"|"+column.getColumnName()+"n");break;case5:System.out.println("5、表和字段都相同,但字段类型不同的内容:"+table.getTableName()+"|"+column.getColumnName()+"|"+column.getDataType());//需要人工判断脚本sb[4].append(table.getTableName()+"|"+column.getColumnName()+"|"+column.getDataType()+"n");break;case6:System.out.println("6、表和字段、字段类型都相同,但字段长度不同的内容:"+table.getTableName()+"|"+column.getColumnName()+"|"+column.getLength());//需要人工判断脚本sb[5].append(table.getTableName()+"|"+column.getColumnName()+"|"+column.getLength()+"n");break;}}/***@authorYUJIYU090将StringBuffer中的值写入文件中**/publicstaticvoidwriteFile()throwsException{String[]fileName={"D://table//生产存在,开发不存在的表.txt","D://table//生产不存在,开发存在的表.txt","D://table//生产存在,开发不存在的字段.txt","D://table//生产不存在,开发存在的字段.txt","D://table//表和字段都相同,但字段类型不同的内容.txt","D://table//表和字段、字段类型都相同,但字段长度不同的内容.txt"};for(inti=0;i<fileName.length;i++){Filefile=newFile(fileName[i]);OutputStreamos=newFileOutputStream(file);os.write(sb[i].toString().getBytes());os.flush();os.close();}}}

我写代码一向是属于有点野路子型的,大师级别的人看了别笑话,希望给出中肯的建议原文发布于我的博客:

解决方案

解决方案二:
额,表示LZ在osc上发过
解决方案三:
其实这里才是首发,后面发现人气太少了,就发到OSC了
解决方案四:
用得着这么费劲么?每个库都把表结构导出来,用文本比较工具比较一下呗。
解决方案五:
先把表导出为文本文件,再用程序比较文件内容,个人感觉能快些。毕竟800多张表。
解决方案六:
你好,我现在在做这个,看了你写的东西,很适合我,DataConvert,ASResultSet这两个包,能给我发一下吗,348685378@qq.com,我的邮箱,谢谢啊
解决方案七:
好贴应该加精
解决方案八:
你好,我现在在做这个,看了你写的东西,很适合我,DataConvert,ASResultSet,Transaction这两个包,能给我发一下吗,582376043@qq.com,我的邮箱,谢谢啊
解决方案九:
引用3楼bao110908的回复:

用得着这么费劲么?每个库都把表结构导出来,用文本比较工具比较一下呗。

确实
解决方案十:
非要写代码去比对?你写的代码还要测试,就算测了还不一定准确,废工又费劲,你们项目经理是怎么同意这种方案的。直接结构导出来,比对工具这么多,分分钟搞定,准确率几乎100%。大项目还敢这么玩,想死了。。。
解决方案十一:
你好,我现在在做这个,看了你写的东西,很适合我,DataConvert,ASResultSet,Transaction这两个包,能给我发一下吗,414715257@qq.com,我的邮箱,谢谢啊

时间: 2024-10-26 21:02:30

有没有什么更好的实现办法?Java对比两个数据库的内容的相关文章

hibernate多表查询返回object,有没有更好的解决办法

问题描述 hibernate多表查询返回object,有没有更好的解决办法 各位大神,您们好!小弟最近才开始学习hibernate,hibernate多表查询返回object的数组,有没有办法让它返回以主表为根对象的对象集合,根对象可以使用get子对象的方法获取到其它的从表映射的对象.fetch="join" <hibernate-mapping> <class name="com.zdsoft.entity.Sysuser" table=&quo

sqlserver-SQLServer2008如何更好的备份一个200多G的数据库

问题描述 SQLServer2008如何更好的备份一个200多G的数据库 SQLServer2008如何更好的备份一个200多G的数据库,不是每次都用完整备份,而是每天备份新增或有所改变的数据,求大家推荐好的方案 解决方案 计划任务,设置增量备份即可. 解决方案二: 查询导出数据 select * from table where date between .... 解决方案三: http://blog.csdn.net/deepwishly/article/details/7951144

谁画质更好?联想S820拍照对比OPPOR819

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;   从诺基亚推出4100万超高像素的Lumia1020,到9月23日支持5秒快门的OPPO N1发布.我们可以看到手机的拍照功能在受到用户的认可的同时,国内外的 手机厂商也在致力于提高手机拍照的画质. 左为联想S820,右为OPPO R819T 今天我们要对比的两款手机均是由国内知名厂商推出的主打拍照手机,两款手机的相机配置在 众多国产手机中已是佼佼者.不同的是,在

更好的管理服务器上的多个数据库

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 每这个实例或者每这个服务器设置这个单一的数据库能够使数据库顾问更方便.然而,这样做很快将加大你的数据库解决措施的本钱,因为你要对你期望托管的每这个数据库购买一台新的服务器或者新的SQL服务器许可证. 为了应对这种价格昂贵的设置,人们一般在这个服务器或者实例上托管多个数据库(也正是多个应用程式).虽然这将减小托管所有这些数据库的本钱,可是,这加

Java 编程技术中汉字问题的分析及解决(转)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日内容: 汉字编码的常识 Java 中文问题的初步认识 Java 中文问题的表层分析及处理 Java 中文问题的根源分析及解决 Java Servlet 中文问题的根源 修改 Servlet.jar 中文乱码的处理函数 参考资料 作者简介在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Jav

Java 编程技术中汉字问题的分析及解决,文件操作

编程|汉字|解决|问题 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的 乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言 默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编 码呢?本文将从汉字编码的常识入手,结合 Java 编程实例,分析以上两个问题并提出 解决它们的方案. 现在 Java 编程语言已经广

Java 编程技术中汉字问题的分析及解决(转自IBM)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合 Java 编

Java 编程技术中汉字问题的分析及解决

编程|汉字|解决|问题 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合 Java 编程实例,分析以上两个问题并提出解决它们的方案. 现在 Java 编程语言已经广泛应用于

Java编程技术中汉字问题的分析及解决

在基于Java语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java语言默认的编码方式是UNICODE,而我们中国人通常使用的文件和数据库都是基于GB2312或者BIG5等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合Java编程实例,分析以上两个问题并提出解决它们的方案. 现在Java编程语言已经广泛应用于互联网世界,早在Sun公司开发Java语言的时候