使用DBCopier進行不同數據庫間的數據移植

DBCopier同樣是在多數據庫環境中,爲了適應數據整理和拷貝而開發的可重用構件。不過,實際上,更多的情況是用在不同的開發過程中由于表結構的修改,而需要對曆史數據進行整理歸一的過程。

DBCopier的工作核心是mission.xml,每一個mission是一個拷貝任務;不同的數據庫連接在connectionset元素中定義,實際上,這與ConnextionManger和DAO中的定義和解釋是一樣的。
如:
<connection-set>
    <connection name="mysql" driver="com.mysql.jdbc.Driver" username="conn" password="abcd">
        <uri><![CDATA[jdbc:mysql://127.0.0.1:3306/daifumd?useUnicode=true&characterEncoding=gb2312]]></uri>
    </connection>   
    <connection name="conn" driver="oracle.jdbc.driver.OracleDriver"
        uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="conn" password="
abcd" />
    <connection name="reso" driver="oracle.jdbc.driver.OracleDriver"
        uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="reso" password="abcd" />
    <connection name="daifu" driver="oracle.jdbc.driver.OracleDriver"
        uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="daifu" password="abcdef" />
    <connection name="system" driver="oracle.jdbc.driver.OracleDriver"
        uri="jdbc:oracle:thin:@127.0.0.1:1521:dkt0" username="system" password="abcdefg" />
</connection-set>

定義了若幹個數據庫連接定義。根據需要,DBCopier可以把不同的數據庫中的表拷貝到另一個數庫的某個或幾個表上,也可以在同一個數據庫中拷貝。

每一個mission是一個任務:
<mission name="sectart" target="mysql" source="mysql.simplebase" condition="type=7" range="*" step="100" index="id" logging="false">
    <query name="read">
        <sql><![CDATA[select * from simplebase WHERE id >= ${MIN} and id < ${MAX}]]></sql>
    </query>
    <query name="write">
<sql>insert into sectart (name,chn,deleted,on_off_line,section,type,remark) values (${name},${chn},${deleted},${on_off_line},${section},${type},${remark})</sql>
    </query>
<field name="type" sname="parentid" ttype="int"/>
<field name="deleted" ttype="int"/>
<field name="on_off_line" ttype="int"/>
</mission>

詳細定義是:
mission代表一个拷贝任务;
mission.(target/source) 分别表明拷贝的目标和来源,结构是(数据源.表名),意为是直接针对表操作,尽管主要由Query实现转录,或者是Clazz,但是在计算步长和数量时仍需要这里的表名。反而是target可以直接数据源名称。
mission.index 指示是以什么域作为拷贝计数的指标,如id;
mission.range;采用1-2000这样的形式,前者是起始,后是终结(参照index);如果是“*”,表示全部拷贝(默认)。
mission.step:步长,即每次动作过程拷贝多少,这点相当于设置缓冲大小;每次执行step的数目,或实际总数(小于step时)
mission.condition是拷贝对象的附加条件;可以直接写作cdata形式;
mission.query元素: 每个mission目前可以定义多个Query对象,但至少包括分别命名为write的Query对象,如果没有mission.clazz作为写入源, 还必须有一个名为read的Query对象;特别注意read对象,如果其中有"WHERE"一定要大写,特别是在condition有东西的时侯;$ {MIN}/${MAX}是程序约定的大值和小值标识,与range配合,即使是“*”,这两个值也是必须的;因为步长选择的时侯需要这两个值
注意:query.sql中如果有域是long/clob型的,一定要摆在最前面,否则可能出错;

mission.clazz元素:{
    对于一些复杂结构的数据对象类型,很难确定为一个表对表的抄录,同时也还包含有多处的互相约束,这时侯需要使用数据对象作为数据源;即每一个对象实例是相 对于一行主表的记录,它的属性是各个基表或子表值;clazz对象tools.xmlobj.Clazz必须实现tools.COPIER接口,并用标准 的setter/getter取/置值;
    clazz.attribute对象;主要包括三个属性,name,value,和type,type用于反射时的class型获得,因此要求完全的名称,以便在程序中Class.forName();
    }

mission.field;{
DBCopier实际上是使用Query.write中的变量获得一个串,然后通过这个串检索qread或者是cread形成一个名值对填充好一个完整的 sql,最后执行这个batchsql完成移植的目的。每个变量串中的域获得值的方式各不相同,特别是在许多情况下转移的过程本身就是对原来不合理的数据 记录方式的重整,(规范化或非规范化),filed就是针对这个需求进行设置。如果没有相对的field设置,则采用默认设置,即名称相同且都是字符串 值;field的逻辑是首先采纳value值,然后按query取值,最后按常规取值;

field.name:该名称应与qwrite中的变量名称之一匹配;否则DBCopier将加以忽略;
field.sname:该名称指老表中的域名称,DBCopier通过这条从cread或qread的rs中读数据;默认地与field.name相同;
field.stype:输入的类型,这条对于使用qread特别重要,尤其对于date类型;
field.ttype:输出的类型,是指插入的类型,主要是因为生成sql时字符串需要使用‘’括起来;
filed.value:   value是设定的值;可用此直接给一行赋值;如果是“system.time”,意思是取System.currentTimeMillis()的值;
field.query:{
    如果该域必须经过特别的查询得到值,就设定所用的query名称,这个query应该已经定义在同一个mission中。
    field.query实际上经历了两个过程,一是以前述的方法获得一个指定的变量;代入query的sql设定,执行这个sql再读取它的值;
    这时field的域含义有重大的修改:
    field.sname指代入field.query.sql中的变量名称,一定要与相应的数据连接中的表.域名称相同;
    field.stype指读这个query结果时的类型;其余意思一样。
    field.filter; 如果这个域在存入新库中时需要过滤更替其中的一些字符串,设置好filter后用这个参数调用。
        }
    注意:query的connetion查询到底是那一个的,常常是错误的关系;
    }

mission.filter,用于对转录过程中的字符串列进行必要的字符替换和过滤;由field调用;

在定義好後,執行:
java DBCopier mission=xxxx;;
程序就會按照步長一段一段地完成數據移植任務,不滿意就重新來一遍。之所以要分割步長,是為了避免多個連接游標在大數據表時溢出出錯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值