数据迁移程序介绍

 

数据迁移说白了就是把数据从一个数据仓库搬到另一个数据仓库。但是如果数据仓库之间的结构不一样的话,就会大大增加迁移的难度。一般的迁移工具只能处理表与表之间、字段之间的简单转换,如果遇上了表结构大不相同的数据迁移,那编写合适的迁移程序就相当必要了。

 

对于一个重构系统而言,由于业务流程改进和代码结构优化,所用及的数据结构也会有很大程度的改变。新系统有些字段可能需要查询旧系统多个表多个字段,经过复杂的逻辑运算后才能确定。如果新旧系统要并行使用一段时间有增量迁移的需求,则更增加了迁移程序的复杂度。不同的系统会有不同的迁移算法,至今也不会有哪一种迁移程序可以涵盖所有的数据迁移需求。本文所列方法只限于新旧系统都是采用hibernate框架进行数据持久化,且新旧系统数据结构有很大不同的情况下使用为佳。

 

采用hibernate进行数据持久化后,数据仓库之间的数据迁移就转换成了对象之间的迁移,我们所要做的无非就是产生新系统的对象然后把它保存,用对象来处理复杂逻辑一向比用单纯的表字段来得更简洁容易。我们就是要架构这样的一个框架,使开发人员只需关注新旧系统对象间的转化,其它的都交由框架去处理。

 

因此我们定义了这样一个接口IDataTransferService,该接口提供两个方法,addupdateadd只对老系统进行新增操作,update除了新增操作外还会对同一对象进行修改操作。相对对象的确认可以通过编程来判断,默认的是根据id值判断。继承IdataTransferService后就是一个对象转换逻辑类。



 

 

IdataTransferService和一个基本实现类BaseServiceImpl,该类实现addupdate方法,在这里要注意的是要做分页和transaction处理。4protected方法,isNeedTransform指示是否要执行transform操作,在特殊情况下,系统只需要执行afterTransform的操作;afterTransform是指执行完transform操作后需要同时进行的一些后续处理;getOldDao指示对旧系统进行数据操作的DAOgetNewDao提示对新系统进行数据操作的DAOtransform是最主要的业务方法,处理新旧系统的对象转换。



 HibernateDaoImpl提供了基本的数据库操作,OldDaoImplNewDaoImpl都继承自它。OldDaoImpl是对旧系统的数据操作DAO,通过setBaseDaoSessionFactory方法指定数据源;getEntityClass指定旧系统的对象类;getAllstart开始取count数量条记录。如果start<0则取全部记录,注意,如果实体没有名为id的属性,则需要重写这个方法,这是为性能考虑。

NewDaoImpl是对新系统的数据操作DAO,通过setBaseDaoSessionFactory方法指定数据源;getEntityClass指定旧系统的对象类;getBySrcEntity根据旧对象查找对应的新对象,有些要通过旧系统实体的联合主键来确定,一般可以用联合主键组合起来的MD5编码来作为新系统对象的主键。



 TransactionSaveService是具有事务的批处理类,它会把分页内的所有对象放在一个事务内处理。


 

public long transData(BaseServiceImpl service, List oldList, boolean isUpdate) {

      long processCount = 0; // 已经处理的记录数

 

      for (int j = 0; j < oldList.size(); j++) {

        IdEntity src = (IdEntity) oldList.get(j);

        if (service.getOldDao().getEntityClass()!=null) {

           src = (IdEntity) service.getOldDao().get(service.getOldDao().getEntityClass(), src.getId());

        }

 

        Object target = null;

        if (service.isNeedTransform()) {

           target = service.getNewDao().getBySrcEntity(service.getEntityClass(), src);

           // 如果新对象中已有记录且不是更新

           if (target != null && !isUpdate) {

              continue;

           }

           if (target == null) {

              try {

                 target = service.getEntityClass().newInstance();

              } catch (Exception e) {

                 e.printStackTrace();

              }

           }

           if (target != null) {

              service.transform(target, src);

              save(service.getNewDao(), target);

 

              processCount++;

           }

        }

        service.afterTransform(target, src);

      }

      return processCount;

   }

 

 

BaseServiceImpladdupdate方法,以update为例

 

@Override

public void update (int startPage, int endPage, String startDate, String endDate) throws NmoException {

      Logger.getLogger(this.getClass()).debug("Begin update by time transform!");

      long beginTime = System.currentTimeMillis();

 

      long processCount = 0; // 已经处理的记录数

      for (int i = startPage; i <= endPage; i++) {

        List oldList = getOldDao().getAll(i, IDataTransferService.PageSize, startDate, endDate);

        if (oldList == null || oldList.isEmpty()) {

           break;

        }

 

        Logger.getLogger(this.getClass()).debug(

              "Processing ... Number(" + IDataTransferService.PageSize + "): " + i);

 

        processCount += getTransactionSaveService().transData(this, oldList, true);

      }

 

      long endTime = System.currentTimeMillis();

      Logger.getLogger(this.getClass()).debug(

           "End transform, total transform: " + processCount + " records, total cost: " + (endTime - beginTime)

                 + "ms");

   }

 

 

至此,数据迁移框架已经成形,我们只需要为每一个新系统实体编写对应的service类,newDao类和oldDao类。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值