<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了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 { @Autowired private StudentMapper studentMapper; @Autowired private HttpUtils httpUtils; @Override public 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是否為null if (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 { @Autowired private 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工具等等。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45