Java数据同步

  • Java方式实现数据同步
    • 业务背景
    • 实现逻辑
    • 使用技术
    • 代码详情
    • 功能小结

Java方式实现数据同步

使用java方式实现两个系统之间数据的同步。

业务背景

在新系统中设置定时任务需要实时把客户系统中的数据及时同步过来,保持数据的一致性。

实现逻辑

1.根据客户提供的接口,本系统中采用Http的Post请求方式获取接口数据。
2.由于客户提供的接口必带页码和页面容量,因此会涉及到多次请求接口才能拿到全量数据,因此相同的操作可以采用递归的方式进行。
3.每次请求一次接口根据页面容量(pageSize)可获取多条数据,此时可以采用批量添加数据库的操作,使用批量SQL添加语句。
4.由于数据同步需要保持两个系统数据的一致性,因此需要使用定时任务并规定同步频率,例如:一天一次或者一天两次。
5.定时任务的使用会产生数据重复的问题,因此根据某个唯一字段建立唯一索引来避免数据重复添加的问题。
6.唯一索引的建立可以避免同一记录重复添加的问题,但是避免不了同一条记录除唯一索引字段之外其它字段对应数据发生变化问题,因此使用replace into添加SQL语句可以解决此问题。
提示: a. 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。 b. 不然的话,直接插入新的数据。

使用技术

1.设置定时任务。
2.采用Http的Post方式获取接口数据。
3.涉及多页数据采用递归方式循环调用。
4.批量操作数据库(replace into)。
5.建立唯一索引避免重复插入数据。

代码详情

1.StudentMapper.java

/*** 批量添加数据同步接口学生数据* @param studentList* @return*/int addBatchStudent(@Param(value = "studentList") List<Student> studentList);

2.SyncStudentServiceImpl.java代码如下:

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ***.common.utils.HttpUtils;
import ***.common.utils.StringUtils;
import ***.entity.sync.Student;
import ***.mapper.sync.StudentMapper;
import ***.service.sync.SyncStudentService;
import ***.vo.StudentVO;
import lombok.extern.slf4j.Slf4j;/*** 数据同步的学生实现类* @author hc* @create 2021/03/25 11:20* @version 1.0* @since 1.0*/
@Service
@Slf4j
public class SyncStudentServiceImpl implements SyncStudentService {@Autowiredprivate StudentMapper studentMapper;@Autowiredprivate HttpUtils httpUtils;@Overridepublic void bulkAddStudent(StudentVO studentVO) {log.info("调取学生接口传的参数对象studentVO:"+studentVO);log.info("开始调取学生接口获取第" + studentVO.getPageIndex() + "页数据");//如何页面容量小于100,则按100计算if(studentVO.getPageSize() < 100) {studentVO.setPageSize(100);}//根据当前页码和页面容量调取获取学生数据接口JSONObject jsonObject = this.sendStudentHttpPost(studentVO);//判断返回JSONObject是否为nullif (StringUtils.isNotNull(jsonObject) && jsonObject.containsKey("errcode") && jsonObject.getInteger("errcode") == 0) {if(jsonObject.containsKey("data")){JSONArray jsonArray = jsonObject.getJSONArray("data");//通过判断获取的jsonObject对象中key值为data是否为null和其 jsonArray的长度来判断是否进行递归//提示:此判断方法好于通过计算总页码的方式来递归拿数据(对获取的total依赖过大,因此放弃此方式)if(jsonObject.getString("data") != null && jsonArray.size() > 0) {log.info("当前数据加载到几页》》》》:{}", studentVO.getPageIndex());//调取批量添加数据this.addStudentCycleData(jsonObject, studentVO);//页码加1,继续调取下一页数据studentVO.setPageIndex(studentVO.getPageIndex() + 1);//采用递归方式直至循环结束this.bulkAddStudent(studentVO);}else {log.info("学生数据同步结束》》》");}}}}/*** 批量添加学生数据* @param jsonObject* @param areaVO* @return*/public void addStudentCycleData(JSONObject jsonObject, StudentVO studentVO){List<Student> studentList = null;//判断jsonArray时候为空if (jsonObject != null && StringUtils.isNotBlank(jsonObject.getString("data"))) {//把JsonArray转成对应实体类集合studentList = JSONObject.parseArray(jsonObject.getString("data"), Student.class);}try {log.info("学生接口第" + studentVO.getPageIndex() + "页数据开始入库...");//调取方法批量进行添加学生数据studentMapper.addBatchStudent(studentList);log.info("学生接口第" + studentVO.getPageIndex() + "页数据入库成功...");} catch (Exception e) {log.error("学生批量添加数据库异常:{}", e.getMessage());}}/*** 根据studentVO(当前页码和页面容量)发送获取学生数据的请求* @param studentVO* @return*/public JSONObject sendStudentHttpPost(StudentVO studentVO){JSONObject jsonObject = null;String studentUrl = "http://*****/async-api/jc/student";try {if (StringUtils.isNotEmpty(studentUrl)) {Map<String, Object> param = new HashMap<>();param.put("pageIndex", studentVO.getPageIndex());param.put("pageSize", studentVO.getPageSize());log.info("开始发起http请求...");jsonObject = httpUtils.sendHttpPost(param, studentUrl);}} catch (Exception e) {log.error("调取客户学生同步接口出现异常:{},页面容量为:{},页码:{}", e.getMessage(), studentVO.getPageSize(), studentVO.getPageIndex());}return jsonObject;}
}

3.StudentVO.java代码如下:

import lombok.Data;
/*** 数据同步接口获取学生数据传的参数VO类* @author hc* @create 2021/3/11 10:35* @version 1.0* @since 1.0*/
@Data
public class StudentVO{//当前页码(初始值为0)private Integer pageIndex = 0;//页码容量private Integer pageSize;
}

4.HttpUtils.java代码如下:

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.Map;/*** Http请求工具类* @author hc* @create 2021/3/4* @version 1.0*/
@Component
@Slf4j
public class HttpUtils {@Autowiredprivate RestTemplate restTemplate;/*** 发送http的post请求方法* @param param* @return*/public JSONObject sendHttpPost(Integer type, Map<String, Object> param, String url){log.info("调取同步接口Url:{}", url);JSONObject jsonObject = null;//发起http的post准备工作HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.add("Content-Type", "application/json");HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(param, httpHeaders);ResponseEntity<String> response = null;try {log.info("param参数为:{}",param.toString());response = restTemplate.postForEntity(url, httpEntity, String.class);} catch (HttpClientErrorException e) {log.error("发起http请求报错信息:{}",e.getResponseBodyAsString());}String bodyData = response.getBody();if (StringUtils.isNotEmpty(bodyData)) {jsonObject = JSONObject.parseObject(bodyData);}return jsonObject;}
}

5.StudentMapper.xml的SQL语句如下:

<!-- 批量添加数据同步接口中获取的学生数据 -->
<insert id="addBatchStudent" parameterType="***.entity.sync.Student">replace into xf_clue_sync_student(id, student_code, student_name, status, create_date, update_date)<foreach collection="studentList" item="student" open="values" separator="," >(#{student.id,jdbcType=BIGINT}, #{student.studentCode,jdbcType=INTEGER}, #{student.studentName,jdbcType=VARCHAR}, #{student.status,jdbcType=INTEGER}, #{student.createDate,jdbcType=VARCHAR}, #{student.updateDate,jdbcType=VARCHAR})</foreach>
</insert>

功能小结

1.定时任务配置相关代码此处不再展示,SpringBoot框架使用注解的方式即可设置定时任务以及调取频率。
2.数据同步接口开发需要根据具体应用场景采用不同的方法,需视情况而定,例如:也可以使用kettle工具等等。

采用Java方式实现数据同步相关推荐

  1. java数据库大量数据同步处理方法记录

    java数据库大量数据同步保存处理方法 一 场景 当有大量数据需要保存到数据库时,此时若是一条一条的保存,将会多次进行I/O交互,而且大量数据还会让数据库崩溃,这个时候就需要进行优化处理. 二 实现 ...

  2. java移库数据同步,库存调拨 java 实现方式

    项目开发中客户提出一个要求: 我只选择商品和数量,完成商品的移库操作 在开发中发现这里商品又有批次的问题,那么计算成本的时候又需要根据批次来计算他的成本,那么这样就产生了几个问题 1.当某个商品的这个 ...

  3. 基于Java方式如何实现数据同步

    本篇内容介绍了"基于Java方式如何实现数据同步"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读, ...

  4. 数据同步之采用时间戳的方法进行增量数据同步(一)

    本文主要介绍源表为单表时,增量数据同步的情况.当源表为多表时,后面的文章会继续介绍. 一.数据同步情况说明 将源数据库S中的A表(将此表称为源表),通过ETL工具同步至目标数据库T的A表(将此表称为目 ...

  5. 几种常见的数据同步方式

    数据仓库的特性之一是集成,即首先把未经过加工处理的.不同来源的.不同形式的数据同步到ODS层,一般情况下,这些ODS层数据包括日志数据和业务DB数据.对于业务DB数据而言(比如存储在MySQL中),将 ...

  6. 大数据之路读书笔记-03数据同步

    大数据之路读书笔记-03数据同步 如第一章所述,我们将数据采集分为日志采集和数据库数据同步两部分.数据同步技术更通用的含义是不同系统间的数据流转,有多种不同的应用场景.主数据库与备份数据库之间的数据备 ...

  7. 使用canal解决Mysql和Redis数据同步问题

    前言 千呼万唤始出来,停了好个月,终于又开始动手写文章了,今天带给大家的是阿里的一个工具Canal,这个工具是企业做数据同步使用的比较多的方案,希望对你有所帮助,喜欢的话请给个好评 工作原理分析 我们 ...

  8. etl数据抽取工具_数据同步工具ETL、ELT傻傻分不清楚?3分钟看懂两者区别

    什么是数据同步工具(ETL.ELT) 数据同步工具ETL或者ELT的作用是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决 ...

  9. 不懂就问:ZooKeeper 集群如何进行数据同步?

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 项 ...

最新文章

  1. 2、ShardingSphere 之 Sharding-JDBC实现水平分表
  2. 前端趋势榜:上周最实用和 yyds 的 10 大前端项目 - 211128
  3. UVA - 10118 Free Candies 记忆化搜索经典
  4. 程序员必备软技能之科技趋势(一)
  5. 机器学习集成模型学习——Boosting集成学习(四)
  6. 详细的redis操作介绍
  7. 它在计算机房的旁边英文,计算机房设备搬迁协议 (中英文)
  8. pandas后几行_天秀!Pandas还能用来写爬虫?
  9. Windows服务器远程桌面访问(两种方法)
  10. 计算机开启后显示器黑屏,电脑打开后显示器黑屏怎么办
  11. 电源设计那些事儿-ppt01
  12. 智商高的人都不爱说话,程序员也是如此吗?
  13. ps制作设计网站登录界面
  14. 毕设模块之一:最新版 微博网络爬虫(可登录版)
  15. html列表横向变纵向,手机版利用 CSS 将横向表格转换成竖向列表显示
  16. 内网穿透工具--Sunny-Ngrok讲解
  17. 教你正确使用文字识别软件ABBYY的转换格式功能
  18. 计网实验c/c++ 电子邮件客户端程序实现发送接收邮件
  19. 西行漫记(20):一路向北
  20. Eclipse 10 hotest-keys

热门文章

  1. AArch64教程第六章
  2. SQL语句 打印输出 九九乘法表
  3. 日语学习-五十音记忆法(下)
  4. C++数据结构与算法—用递归方法求二叉树的叶子结点数
  5. Greenfoot游戏——推箱子
  6. excel数据分析思维导图整理
  7. PHP如何取消提醒缺少运行库,Xampp2016打开提示缺少运行库的解决方法(亲测可行)...
  8. 百度全民VIP狂欢节打通优质内容平台:对于内容行业有三个启示
  9. 手把手教你做一款音乐播放器(csharp的winform)
  10. 赵艳丽谈下自己的一些经历和一个项目