92、先比较,再更新,速度极快

  • 2021-12-31
  • Admin

一、问题

一个系统,经常需要和上下游同步数据,比如账务dts从crm同步客户数据,新dts从老dts同步用户数据,ehr需要把xx数据写进redis。

二、常见的办法

1、数据库之间的同步

先删除所有数据,再保存所有数据;整体作为一个事务。

问题:速度很慢。如果表的id被其它业务关联了,也不方便。

更好的办法:先从系统的数据库表,查询存在的数据;和需要同步查询的数据作比较, 判断哪些是新增的、哪些是删除的、哪些是修改的。

即:先比较再更新。

2、向es写数据

最差的办法:删除所有数据,重建索引。xx就这么干过?

一般的办法:直接调用es的接口,为所有数据,重建索引。大概有个index方法,传入数据。

更好的办法:先从es查询数据,和数据库的数据做比较,如果变化了,才有必要更新es的数据。

三、初步分析

1、系统的数据变化,通常没有那么多,那么频繁

2、数据库、es的修改删除等操作,尤其是带了事务,会非常慢;而查询是极快的

3、频繁操作数据库,不但自己的系统慢,可能还影响到系统内的相关模块的db访问速度,影响到数据库相关的其它系统服务。

四、代码示例

import java.util.List;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

@Service

public class AuthUserService extends MpServiceImpl {

    @Autowired

    private OldAuthUserMapper oldAuthUserMapper;

    // 返回变化的

    public Integer sync() {

        Wrapper queryWrapper = Wrappers.query();

        List oldList = oldAuthUserMapper.selectList(queryWrapper);

        AuthUser query = new AuthUser();

        query.setIsDeleted(YnEnum.NO.getCode());

        List dbList = super.list(query);

        Map dbUserMap = ListKit.listToMap(dbList, AuthUser::getOldId);

        List changedList = Lists.newArrayList();

        for (OldAuthUser oldAuthUser : oldList) {

            try {

                one(dbUserMap, changedList, oldAuthUser);

            catch (Exception e) {

                log.error("AuthUserService sync error", e);

            }

        }

        return changedList.size();

    }

    private void one(Map dbUserMap, List newList, OldAuthUser oldAuthUser) {

        Integer oldId = oldAuthUser.getId();

        AuthUser dbUser = dbUserMap.get(oldId);

        if (dbUser != null) {

            boolean changed = changed(oldAuthUser, dbUser);

            if (changed) {

                AuthUser newDbUser = newDbUser(oldAuthUser, dbUser);

                newList.add(newDbUser);

                super.updateById(newDbUser);

            }

        else {

            AuthUser saveDbUser = saveDbUser(oldAuthUser);

            newList.add(saveDbUser);

            super.save(saveDbUser);

        }

    }

    private AuthUser newDbUser(OldAuthUser oldAuthUser, AuthUser dbUser) {

        AuthUser newDbUser = BeanKit.build(oldAuthUser, AuthUser.class);

        newDbUser.setId(dbUser.getId());

        newDbUser.setUpdateTime(DateKit.now());

        return newDbUser;

    }

    private static boolean changed(OldAuthUser oldAuthUser, AuthUser dbUser) {

        // str

        if (StringKit.notEquals(oldAuthUser.getUsername(), dbUser.getUsername())) {

            return true;

        }

        if (StringKit.notEquals(oldAuthUser.getPassword(), dbUser.getPassword())) {

            return true;

        }

        if (StringKit.notEquals(oldAuthUser.getLastName(), dbUser.getLastName())) {

            return true;

        }

        if (StringKit.notEquals(oldAuthUser.getFirstName(), dbUser.getFirstName())) {

            return true;

        }

        if (StringKit.notEquals(oldAuthUser.getEmail(), dbUser.getEmail())) {

            return true;

        }

        // int

        if (EqualsKit.notEquals(oldAuthUser.getIsActive(), dbUser.getIsActive())) {

            return true;

        }

        if (EqualsKit.notEquals(oldAuthUser.getIsStaff(), dbUser.getIsStaff())) {

            return true;

        }

        if (EqualsKit.notEquals(oldAuthUser.getIsSuperuser(), dbUser.getIsSuperuser())) {

            return true;

        }

        // date

        if (EqualsKit.notEquals(oldAuthUser.getDateJoined(), dbUser.getDateJoined())) {

            return true;

        }

        if (EqualsKit.notEquals(oldAuthUser.getLastLogin(), dbUser.getLastLogin())) {

            return true;

        }

        return false;

    }

    private AuthUser saveDbUser(OldAuthUser oldAuthUser) {

        AuthUser authUser = BeanKit.build(oldAuthUser, AuthUser.class);

        authUser.setId(null);

        authUser.setOldId(oldAuthUser.getId());

        authUser.setCreateTime(DateKit.now());

        authUser.setUpdateTime(DateKit.now());

        authUser.setIsDeleted(YnEnum.NO.getCode());

        return authUser;

    }

     

}

原文:https://blog.csdn.net/FansUnion/article/details/122251091

联系站长

QQ:769220720