这是使用DBCopier的附加文档。针对需要使用 Clazz read情况。DBCopier最早的出现是现实中的需要:常常需要把旧的或分散的系统(数据库)中的记录按要求倒到新的数据库并建立相应的联系。这时侯,很自然就会产生一个设想:这些程序是否可以以某种方式实现重用呢?
DBCopier 本来是针对数据库一行对一行的过录。对于多子表和集合属性的表类型,使用Clazz方式与源数据的一行记录绑定,这里需要写一个CLAZZ 的类,称为read class. CLASS要实现DBCOPIER接口,接口要求三个方法:setConnection(java.sql.Connection);init()和 isAvailable();
setConnection是设入需要的连接;
init()实际上就是load,即把相应的记录载入这个实例;然后,通过isAvailable确认载入(绑定)是否成功。
rclass的本质是通过反射方式,由DBCopeir在使用中抽取相应的值,形成提交数据库执行的sqlbatch.,提取和读取的域定义,由missioin记录中的clazz对象属性定义:
例:
<mission name="statics" target="oracle.department" source="oracle.department" range="*" step="100" index="id">
<clazz name="read" type="DoCount" index="id">
<attribute id="1" name="count" value="READ" type="int.class" stype="int"/>
<attribute name="table" value="order" type="java.lang.String"/>
<attribute name="keyname" value="departmentid" type="java.lang.String"/>
</clazz>
<query name="read">
<sql><![CDATA[select id from department WHERE id>= ${MIN} and id < ${MAX}]]></sql>
</query>jv
<query name="write">
<sql>update department set statics=${count} where id=${id}</sql>
</query>
<field name="count" ttype="int" stype="int"/>
<field name="id" ttype="int" stype="int"/>
</mission>
上例定义了一个使用cread的data copy 的mission。这个数据整理任务是从dep表中按ID检索order定单表中各个部门的定单总数,然后更新这个字段,以便供报表采用。由于这不是简单的表表行行对应的过录,所以使用cread.
文档clazz部分:
mission.clazz元素:{
对于一些复杂结构的数据对象类型,很难确定为一个表对表的抄录,同时也还包含有多处的互相约束,这时侯需要使用数据对象作为数据源;即每一个对象实例是相对于一行主表的记录,它的属性是各个基表或子表值;clazz对象必须实现tools.COPIER接口,并用标准的setter/getter取/置值;
clazz.attribute对象;主要包括五个属性,id,name,value,index和type,stype,type用于反射时的class型获得,因此要求完全的名称,以便在程序中Class.forName();
index是指代入CREAD对象中的属性名字
value="READ",意即从当前的RS行中读取命名数据;否则将直接取为OBJECT
}
attribute是一个类对象,用于向clazz提供运行必须的参数。
id:这个值与一般指的ID不同,实际上由于这个取值很可能是从某一个Resultset行中读数据,如果不是名值形式而是象rs.getInt(1),那么那个“1”就是由ID提供的,在这里,它指读取RS第几行的值。它默认为-1,此时就采用名值方式读取。
name:唯一识别这个attribute;;
value:如果不是读而是直接赋值的,就把值赋入,如果是READ,那么就从RS中读取;
index:这实际上指示使用那一个键作为这个类与数据行的绑定依据。
type:设入目标时是什么数据类型;
stype读取时是什么数据类型。
DoCount.java代码是:
package tools.copier;
import java.sql.*;
import java.io.*;
import log.*;
public class DoCount implements tools.COPIER{
private String table;
private String keyname;
private int count;
private boolean available =true;
private int id;
private static Loger logger =(Loger)Loger.getLogger(tools.Constants.LOGGER_DAIFU_KEY);
//keyname,table,count;
private java.sql.Connection conn;
public void setConnection(java.sql.Connection conn){
this.conn =conn;
}
public void init() throws Exception {
if(id<=0 || conn==null) throw new Exception("id<=0 or conn==null");
count=0;
String sql ="SELECT count(*) FROM "+table+" WHERE "+keyname+"="+this.id;
java.sql.Statement stmt =null;
java.sql.ResultSet rs =null;
try{
stmt =conn.createStatement();
rs =stmt.executeQuery(sql);
rs.next();
count =rs.getInt(1);
}catch(Exception ex){
logger.error("id:="+id+";imgcount():="+ex.getMessage()+";sql:="+sql,getClass());
}finally{
rs.close();
stmt.close();
}
}
public void setId(int para){
this.id =para;
}
public int getId(){
return this.id;
}
public void setAvailable(boolean para){
this.available =para;
}
public boolean isAvailable(){
return this.available;
}
public void setTable(String para){
this.table =para;
}
public String getTable(){
return this.table;
}
public void setKeyname(String para){
this.keyname =para;
}
public String getKeyname(){
return this.keyname;
}
public void setCount(int para){
this.count =para;
}
public int getCount(){
return this.count;
}
}//end class
关键是init()方法;
执行:java DBCopier mission=statics;
DBCopier就按department的ID先后,每100个步长执行一周;读取ID,每次新成一个新的doCount对象,代入id,以及tablename,keyname等,(可以统计不同的表),然后在一个循环中把从这个doCount中(有多少行就有多少个doCount)的域值,这里是count/id,生成一串的:update xxx set statis=xxx where id=222的SQL;然后executeBatch,就完成了。
DBCopier 本来是针对数据库一行对一行的过录。对于多子表和集合属性的表类型,使用Clazz方式与源数据的一行记录绑定,这里需要写一个CLAZZ 的类,称为read class. CLASS要实现DBCOPIER接口,接口要求三个方法:setConnection(java.sql.Connection);init()和 isAvailable();
setConnection是设入需要的连接;
init()实际上就是load,即把相应的记录载入这个实例;然后,通过isAvailable确认载入(绑定)是否成功。
rclass的本质是通过反射方式,由DBCopeir在使用中抽取相应的值,形成提交数据库执行的sqlbatch.,提取和读取的域定义,由missioin记录中的clazz对象属性定义:
例:
<mission name="statics" target="oracle.department" source="oracle.department" range="*" step="100" index="id">
<clazz name="read" type="DoCount" index="id">
<attribute id="1" name="count" value="READ" type="int.class" stype="int"/>
<attribute name="table" value="order" type="java.lang.String"/>
<attribute name="keyname" value="departmentid" type="java.lang.String"/>
</clazz>
<query name="read">
<sql><![CDATA[select id from department WHERE id>= ${MIN} and id < ${MAX}]]></sql>
</query>jv
<query name="write">
<sql>update department set statics=${count} where id=${id}</sql>
</query>
<field name="count" ttype="int" stype="int"/>
<field name="id" ttype="int" stype="int"/>
</mission>
上例定义了一个使用cread的data copy 的mission。这个数据整理任务是从dep表中按ID检索order定单表中各个部门的定单总数,然后更新这个字段,以便供报表采用。由于这不是简单的表表行行对应的过录,所以使用cread.
文档clazz部分:
mission.clazz元素:{
对于一些复杂结构的数据对象类型,很难确定为一个表对表的抄录,同时也还包含有多处的互相约束,这时侯需要使用数据对象作为数据源;即每一个对象实例是相对于一行主表的记录,它的属性是各个基表或子表值;clazz对象必须实现tools.COPIER接口,并用标准的setter/getter取/置值;
clazz.attribute对象;主要包括五个属性,id,name,value,index和type,stype,type用于反射时的class型获得,因此要求完全的名称,以便在程序中Class.forName();
index是指代入CREAD对象中的属性名字
value="READ",意即从当前的RS行中读取命名数据;否则将直接取为OBJECT
}
attribute是一个类对象,用于向clazz提供运行必须的参数。
id:这个值与一般指的ID不同,实际上由于这个取值很可能是从某一个Resultset行中读数据,如果不是名值形式而是象rs.getInt(1),那么那个“1”就是由ID提供的,在这里,它指读取RS第几行的值。它默认为-1,此时就采用名值方式读取。
name:唯一识别这个attribute;;
value:如果不是读而是直接赋值的,就把值赋入,如果是READ,那么就从RS中读取;
index:这实际上指示使用那一个键作为这个类与数据行的绑定依据。
type:设入目标时是什么数据类型;
stype读取时是什么数据类型。
DoCount.java代码是:
package tools.copier;
import java.sql.*;
import java.io.*;
import log.*;
public class DoCount implements tools.COPIER{
private String table;
private String keyname;
private int count;
private boolean available =true;
private int id;
private static Loger logger =(Loger)Loger.getLogger(tools.Constants.LOGGER_DAIFU_KEY);
//keyname,table,count;
private java.sql.Connection conn;
public void setConnection(java.sql.Connection conn){
this.conn =conn;
}
public void init() throws Exception {
if(id<=0 || conn==null) throw new Exception("id<=0 or conn==null");
count=0;
String sql ="SELECT count(*) FROM "+table+" WHERE "+keyname+"="+this.id;
java.sql.Statement stmt =null;
java.sql.ResultSet rs =null;
try{
stmt =conn.createStatement();
rs =stmt.executeQuery(sql);
rs.next();
count =rs.getInt(1);
}catch(Exception ex){
logger.error("id:="+id+";imgcount():="+ex.getMessage()+";sql:="+sql,getClass());
}finally{
rs.close();
stmt.close();
}
}
public void setId(int para){
this.id =para;
}
public int getId(){
return this.id;
}
public void setAvailable(boolean para){
this.available =para;
}
public boolean isAvailable(){
return this.available;
}
public void setTable(String para){
this.table =para;
}
public String getTable(){
return this.table;
}
public void setKeyname(String para){
this.keyname =para;
}
public String getKeyname(){
return this.keyname;
}
public void setCount(int para){
this.count =para;
}
public int getCount(){
return this.count;
}
}//end class
关键是init()方法;
执行:java DBCopier mission=statics;
DBCopier就按department的ID先后,每100个步长执行一周;读取ID,每次新成一个新的doCount对象,代入id,以及tablename,keyname等,(可以统计不同的表),然后在一个循环中把从这个doCount中(有多少行就有多少个doCount)的域值,这里是count/id,生成一串的:update xxx set statis=xxx where id=222的SQL;然后executeBatch,就完成了。