데이터 이전 - 데 이 터 를 SQLServer 에서 PostgreSQL 로 이전 합 니 다.
144535 단어 데이터 구조
필요 배경
프로젝트 재 구성 수요 로 인해 현재 데 이 터 를 SQLServer 에서 PostgreSQL 로 옮 깁 니 다. 원래 프로젝트 는 단일 프로젝트 (즉, 프로젝트 표 에 영원히 하나의 데이터 만 있 음) 이기 때문에 현재 여러 프로젝트 를 하나의 데이터 베이스 로 옮 깁 니 다. 그러면 프로젝트 표 에 여러 프로젝트 가 나타 납 니 다 (이때 id 는 반드시 충돌 합 니 다).
분석 하여 해결 하 다
데이터베이스 의 다른 소스 문 제 를 해결 하 다.
* 8195: 8195: 이때 의 데이터 이전 은 하나의 데이터 베이스 에서 다른 같은 데이터 베이스 형식의 다른 데이터 베이스 로 이전 하 는 것 이 아니 라 SQLServer 에서 PostgreSQL 로 이전 하기 때 문 입 니 다 (데이터 베 이 스 는 서로 다른 소스).이때 우리 가 먼저 직면 한 것 은 데이터베이스 가 서로 다른 표 구조 문장의 차이성 문제 이다.
이 문 제 를 해결 하기 위해 저 는 다음 과 같은 해결 방안 을 찾 았 습 니 다.
spring-sqlserver
과 spring-postgresql
이다.전 자 는 데이터 읽 기 (SQLServer 에서) 에 만 사용 되 고 후 자 는 데이터 쓰기 (PostgreSQL 에서) 에 만 사 용 됩 니 다.비고, 여기
spring-sqlserver
는 앞의 글 에서 데이터 시트 의 파일 바이트 흐름 을 읽 는 것 을 말 하기 때문에 spring-sqlserver
모듈 과 관련 된 소스 코드 는 앞의 글 에서 직접 표시 되 지 않 습 니 다.데이터 양 이 너무 많은 문 제 를 해결 하 다.
가 져 와 야 할 데이터 의 양 이 많 고 약 30G 이기 때문에 저 는 예전 과 똑 같은 페이지 조회 전략 을 사 용 했 습 니 다. 여기 서 저 희 는 설정 파일 을 통 해 페이지 별로 조회 하 는 정보 항목 수 를 수 동 으로 설정 할 수 있 습 니 다. 여기 서 저 는 100 개 로 설정 되 었 습 니 다. 즉, 매번
spring-sqlserver
에서 100 개의 정 보 를 읽 고 JPA 를 통 해 대량으로 spring-postgresql
에 삽입 한 것 입 니 다.표 의 모든 정 보 를 다 옮 겨 다 닐 때 까지.읽 기보 다 쓰기 가 느 린 문 제 를 해결 합 니 다.
읽 기보 다 쓰기 가 느 린 문 제 를 해결 하기 위해 저 는 Fixed ThreadPool 스 레 드 풀 스 레 드 풀 을 사용 합 니 다. 수 동 으로 스 레 드 를 설정 합 니 다 (테스트 에서 10 개의 스 레 드 를 사 용 했 습 니 다). 하지만 스 레 드 풀 을 사용 하지 않 는 방법 을 작 성 했 습 니 다.
다시 말 하면 저 는 모두 두 가지 방안 이 있 습 니 다. 하 나 는 스 레 드 탱크 를 사용 하고 다른 하 나 는 스 레 드 탱크 를 사용 하지 않 습 니 다.
여기 서 주의해 야 할 것 은 Fixed ThreadPool 의 고정 적 인 결함 때문이다. 즉, 내 가 활성 화 된 스 레 드 수량 을 2 로 설정 하면 현재 활성 화 된 스 레 드 수량 은 확실히 2 이지 만 그 스 레 드 총 수 는 2 가 아니 라 전체 스 레 드 풀 을 차지 하 는 것 이다.다시 말 하면 남 은 스 레 드 는 온라인 스 레 드 풀 에서 줄 을 서서 실행 할 때 까지 큰 문제 가 존재 한 다 는 것 이다. 바로 Feign 의 호출 시간 초과 문제 이다. 즉,
spring-postgresql
요청 이 발생 하면 앞의 정보 요청 은 정상적으로 진행 되 지만 뒤의 요청 은 연결 시간 초과 가 발생 한 다 는 것 이다.(시간 이 초 과 될 때 까지 Fixed ThreadPool 스 레 드 풀 스 레 드 풀 에서 계속 기 다 려 달라 고 요청 하기 때 문 입 니 다.) 이 로 인해 후속 모든 요청 이 실패 할 수 있 습 니 다. 따라서 정보 요청 이 완전 하지 않 을 때 까지 Hystrix, ribbon 등 을 가능 한 한 닫 아야 합 니 다. 안전 을 위해 서 는 비 스 레 드 풀 방식 을 추천 합 니 다.메 인 키 충돌 문제 해결
『 8195 』 메 인 키 충돌 문 제 를 해결 하기 위해 저 는 다음 과 같은 방법 을 사 용 했 습 니 다.
id
를 id_v
로 변경 하고 새로운 메 인 키 id_k
를 생 성 합 니 다.소스 코드
핵심 의존
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.cloud
spring-cloud-starter-hystrix
org.springframework.boot
spring-boot-starter-data-jpa
org.postgresql
postgresql
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.1
org.springframework.cloud
spring-cloud-starter-feign
com.squareup.okhttp3
okhttp
자바 소스 코드
도구 클래스
TimeFormatUtil
package com.lyc.postgresql.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* @author: zhangzhenyi
* @date: 2019/4/11 16:52
* @description:
**/
public class TimeFormatUtil {
//
private long startTime = 0;
//
private long endTime = 0;
/**
* TimeFormatUtil
* @return
*/
public static TimeFormatUtil newTimeFormatUtil(){
return new TimeFormatUtil();
}
/**
*
* @return
*/
public void setStartTime(){
this.startTime = new Date().getTime();
}
/**
*
* @return
*/
public void setEndTime(){
this.endTime = new Date().getTime();
}
/**
*
* @return
*/
public String getSpendTime(){
//
long spendTime = this.endTime - this.startTime;
//
return timeToString(spendTime);
}
/**
* long
* @param spendTime
* @return
*/
private String timeToString(long spendTime) {
//
long millis = spendTime % 1000;
//
long secondTemp = spendTime / 1000;
//
long hour = secondTemp / 3600;
//
secondTemp = secondTemp % 3600;
//
long minutes = secondTemp / 60;
//
long second = secondTemp % 60;
//
return " :" + hour + " " + minutes + " " + second + " " + millis + " ";
}
/**
*
* @param dateString
* @return
*/
public String toDate(String dateString) throws ParseException {
Locale localeUS = new Locale("en","US");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy",localeUS);
Date date = simpleDateFormat.parse(dateString);
//2019-03-19 07:14:04
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
}
FieldFormatUtil
package com.lyc.postgresql.util;
import com.google.common.collect.Maps;
import lombok.var;
import java.util.Date;
import java.util.Map;
/**
* @author: zhangzhenyi
* @date: 2019/3/29 11:22
* @description: Map
**/
public class FieldFormatUtil {
private final Map<String,Object> map;
private final DataConvertUtil dataConvertUtil;
/**
* FieldFormatUtil
* @param map
*/
public FieldFormatUtil(Map<String,Object> map) {
if(null != map) { // ,
this.map = map;
} else { //
this.map = Maps.newHashMap();
}
dataConvertUtil = DataConvertUtil.newDataConvertUtil();
}
/**
* FieldFormatUtil
* @param map
* @return
*/
public static FieldFormatUtil newFieldFormatUtil(Map<String,Object> map){
return new FieldFormatUtil(map);
}
/**
*
* @param k
* @return
*/
public int getInt(String k){
var obj = this.map.get(k);
return dataConvertUtil.getInt(obj);
}
/**
* Long
* @param k
* @return
*/
public Long getLong(String k) {
var obj = this.map.get(k);
return dataConvertUtil.getLong(obj);
}
/**
* String
* @param k
* @return
*/
public String getString(String k) {
var obj = this.map.get(k);
return dataConvertUtil.getString(obj);
}
/**
* Double
* @param k
* @return
*/
public Double getDouble(String k) {
var obj = this.map.get(k);
return dataConvertUtil.getDouble(obj);
}
/**
*
* @param k
* @return
*/
public Date getDate(String k) {
var obj = this.map.get(k);
return dataConvertUtil.getDate(obj);
}
/**
* double
* @param k
* @return
*/
public float getFloat(String k) {
var obj = this.map.get(k);
return dataConvertUtil.getFloat(obj);
}
}
DataConvertUtil
package com.lyc.postgresql.util;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import java.util.Date;
/**
* @author: zhangzhenyi
* @date: 2019/3/29 11:37
* @description:
**/
@Slf4j
@NoArgsConstructor
public class DataConvertUtil {
/**
* DataConvertUtil
* @return
*/
public static DataConvertUtil newDataConvertUtil(){
return new DataConvertUtil();
}
/**
*
* @param o
* @return
*/
public String getString(Object o){
String str = String.valueOf(o);
if("null".equals(str) ){
return null;
}
return String.valueOf(o);
}
/**
*
* @param o
* @return
*/
public Long getLong(Object o){
return Long.valueOf(String.valueOf(o));
}
/**
* int
* @return
*/
public int getInt(Object o){
String str = String.valueOf(o);
if("null".equals(str) ){
return 0;
}
return Integer.valueOf(str);
}
/**
* Double
* @param o
* @return
*/
public double getDouble(Object o){
return Double.valueOf(String.valueOf(o));
}
/**
* Date
* @param obj
* @return
*/
public Date getDate(Object obj) {
if(obj instanceof Long){ // long
// Long
Long timeLong = Long.valueOf(String.valueOf(obj));
// long DateTime
DateTime dateTime = new DateTime(timeLong);
// Long
return dateTime.toDate();
} else { //
return null;
}
}
/**
* double
* @param obj
* @return
*/
public float getFloat(Object obj) {
if(obj != null){
return Float.valueOf(String.valueOf(obj));
}
return 0L;
}
}
유 니 버 설 모듈
CommonConstant
package com.lyc.postgresql.common;
/**
* @author: zhangzhenyi
* @date: 2019/4/16 16:07
* @description:
**/
public class CommonConstant {
public interface TableVersion{
String PROJECT_ID = "projectId";
}
}
EntityConvert
package com.lyc.postgresql.common;
import java.util.Map;
/**
* @author: zhangzhenyi
* @date: 2019/3/29 11:16
* @description:
**/
public interface EntityConvert<T> {
T formatToEntity(Map<String,Object> map);
}
EntityFunction
package com.lyc.postgresql.common;
import java.util.Map;
/**
* @author: zhangzhenyi
* @date: 2019/3/30 10:26
* @description:
**/
@FunctionalInterface
public interface EntityFunction {
EntityModel convertToEntity(Map<String,Object> map);
}
EntityModel
package com.lyc.postgresql.common;
/**
* @author: zhangzhenyi
* @date: 2019/3/30 11:17
* @description:
**/
public class EntityModel {
}
EntityRepository
package com.lyc.postgresql.common;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author: zhangzhenyi
* @date: 2019/3/30 9:55
* @description: Repository
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class EntityRepository {
private String tableName;
private EntityFunction entityFunction;
private JpaRepository jpaRepository;
}
NumberThreads
package com.lyc.postgresql.common;
import lombok.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author: zhangzhenyi
* @date: 2019/4/2 16:04
* @description:
**/
@Component
@Getter
@Setter
public class NumberThreads {
//
@Value("${thread.numberTreads}")
private String numberThreads;
//
@Value("${pagequery.cycleTime}")
private String cycleTime;
}
실체 류
GcFilenum
package com.lyc.postgresql.entity;
import com.lyc.postgresql.common.EntityModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.util.Date;
/**
* @author: zhangzhenyi
* @date: 2019/4/4 16:05
* @description: filenum
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class GcFilenum extends EntityModel {
@Id
@GeneratedValue
private Long id_k;
private String id_v;
private String mid;
private String topid;
private String flag;
private Integer nlevel;
private String str;
private String spstr;
private String content;
private Date createTime;
// id
private Long projectId;
}
생략 하 다.
Feign 원 격 호출
ItemFeignClient
package com.lyc.postgresql.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
import java.util.Map;
/**
* Feign
*/
@FeignClient(value = "sqlserver-server") // Feign
public interface ItemFeignClient {
/**
*
* @param table
* @return
*/
@GetMapping("/countFrom/{table}")
int countFrom(@PathVariable("table") String table);
/**
*
* @param table
* @param sortedField
* @param start
* @param size
*/
@GetMapping("/selectListPageQueryFrom/{table}/{sortedField}/{start}/{size}")
List<Map<String,Object>> selectListPageQuery(@PathVariable("table") String table, @PathVariable("sortedField") String sortedField, @PathVariable("start") int start, @PathVariable("size") int size);
}
SQLServer
CollectionTables
package com.lyc.postgresql.sqlServer;
import com.google.common.collect.Lists;
import com.lyc.postgresql.sqlServer.tables.Tables;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* @author: zhangzhenyi
* @date: 2019/3/29 15:39
* @description: , List
**/
@Slf4j
public class CollectionTables {
private final List<Tables> tablesList = Lists.newArrayList();
/**
* CollectionTables
* @return
*/
public static CollectionTables newCollectionTables(){
return new CollectionTables();
}
public List<Tables> getTables(){
for(Tables table : Tables.values()){
log.info(" :{}, :{}",table.getTableName(),table.getSortedField());
tablesList.add(table);
}
return tablesList;
}
}
Tables
package com.lyc.postgresql.sqlServer.tables;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum Tables {
INTERFACE("interface","listId")
,FILENUM("filenum","mid")
...;
private String tableName;
private String sortedField;
}
데이터 변환
FilenumConvert
package com.lyc.postgresql.targetDataConvert;
import com.lyc.postgresql.common.CommonConstant;
import com.lyc.postgresql.common.EntityConvert;
import com.lyc.postgresql.entity.GcFilenum;
import com.lyc.postgresql.util.FieldFormatUtil;
import java.util.Date;
import java.util.Map;
/**
* @author: zhangzhenyi
* @date: 2019/4/4 16:18
* @description: Filenum
**/
public class FilenumConvert implements EntityConvert<GcFilenum> {
@Override
public GcFilenum formatToEntity(Map<String, Object> map) {
FieldFormatUtil field = FieldFormatUtil.newFieldFormatUtil(map);
return GcFilenum.builder()
.id_v(field.getString( "id"))
.mid(field.getString( "mid"))
.topid(field.getString( "topid"))
.flag(field.getString("flag"))
.nlevel(field.getInt( "nlevel"))
.str(field.getString( "str"))
.spstr(field.getString( "spstr"))
.content(field.getString("content"))
.createTime(new Date())
.projectId(field.getLong(CommonConstant.TableVersion.PROJECT_ID))
.build();
}
public static FilenumConvert newFilenumConvert() { return new FilenumConvert();}
}
다른 생략.
변환 함수 호출
FilenumConvertFunction
package com.lyc.postgresql.convert;
import com.lyc.postgresql.common.EntityFunction;
import com.lyc.postgresql.common.EntityModel;
import com.lyc.postgresql.targetDataConvert.FilenumConvert;
import java.util.Map;
/**
* @author: zhangzhenyi
* @date: 2019/4/4 16:14
* @description: FilenumConvert Function
**/
public class FilenumConvertFunction implements EntityFunction {
@Override
public EntityModel convertToEntity(Map<String, Object> map) {
FilenumConvert filenumConvert = FilenumConvert.newFilenumConvert();
return filenumConvert.formatToEntity(map);
}
}
다른 생략.
repository
FilenumRepository
package com.lyc.postgresql.repository;
import com.lyc.postgresql.entity.GcFilenum;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Filenum Repository
*/
public interface FilenumRepository extends JpaRepository<GcFilenum,Long> {
}
다른 생략.
service
CollectionRepositoryService
package com.lyc.postgresql.service;
import com.google.common.collect.Lists;
import com.lyc.postgresql.convert.*;
import com.lyc.postgresql.repository.*;
import com.lyc.postgresql.common.EntityFunction;
import com.lyc.postgresql.common.EntityRepository;
import com.lyc.postgresql.sqlServer.tables.Tables;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author: zhangzhenyi
* @date: 2019/3/30 9:53
* @description: Repository
**/
@Service
public class CollectionRepositoryService {
@Autowired
InterfaceRepository interfaceRepository;
@Autowired
FilenumRepository filenumRepository;
//
/**
* Repository
* @return
*/
public List<EntityRepository> getRepositories(){
List<EntityRepository> entityRepositoryList = Lists.newArrayList();
// Interface
EntityFunction interfaceFunction = new InterfaceConvertFunction();
EntityRepository interfaceEntityRepository = EntityRepository.builder()
.tableName(Tables.INTERFACE.getTableName())
.jpaRepository(interfaceRepository)
.entityFunction(interfaceFunction)
.build();
// filenum
EntityFunction filenumFunction = new FilenumConvertFunction();
EntityRepository filenumEntityRepository = EntityRepository.builder()
.tableName(Tables.FILENUM.getTableName())
.jpaRepository(filenumRepository)
.entityFunction(filenumFunction)
.build();
//
//
entityRepositoryList.add(interfaceEntityRepository);
entityRepositoryList.add(filenumEntityRepository);
// 。
return entityRepositoryList;
}
}
CopyCoreService
package com.lyc.postgresql.service;
import com.google.common.collect.Lists;
import com.lyc.postgresql.common.CommonConstant;
import com.lyc.postgresql.common.EntityFunction;
import com.lyc.postgresql.common.EntityModel;
import com.lyc.postgresql.common.EntityRepository;
import com.lyc.postgresql.feign.ItemFeignClient;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
/**
* @author: zhangzhenyi
* @date: 2019/3/28 18:55
* @description: PostgreSQL ( )
**/
@SuppressWarnings("ConstantConditions")
@Slf4j
@Service
public class CopyCoreService {
@Autowired
CollectionRepositoryService collectionRepositoryService;
public void copyCore(ExecutorService executorService, ItemFeignClient personFeignClient, String table, String sortedField, int start, int size) {
executorService.execute(() -> {
// ,
List<EntityModel> entityModelList = Lists.newArrayList();
// ,
List<Map<String,Object>> entityList = personFeignClient.selectListPageQuery(table,sortedField,start,size);
entityList.forEach(map -> {
log.info(map.toString());
//
EntityModel entityModel = getEntityModel(map);
//
entityModelList.add(entityModel);
});
if(entityModelList.size() > 0){ // ,
//
choiceRepository(entityModelList,entityList);
}
});
}
/**
*
* @param itemFeignClient Feign
* @param table
* @param sortedField
* @param start
* @param size
*/
public void copyCore(ItemFeignClient itemFeignClient, String table, String sortedField, int start, int size, Long projectId) {
// ,
List<EntityModel> entityModelList = Lists.newArrayList();
// ,
List<Map<String,Object>> entityList = itemFeignClient.selectListPageQuery(table,sortedField,start,size);
entityList.forEach(map -> {
// map projectId
map.put(CommonConstant.TableVersion.PROJECT_ID,projectId);
log.info(map.toString());
//
EntityModel entityModel = getEntityModel(map);
//
entityModelList.add(entityModel);
});
if(entityModelList.size() > 0){ // ,
//
choiceRepository(entityModelList,entityList);
}
}
/**
* ,
* @param entityModelList
* @param entityList
*/
@HystrixCommand(
fallbackMethod = "copyFallback" //
)
private void choiceRepository(List<EntityModel> entityModelList, List<Map<String, Object>> entityList) {
//
String tableName = (String) entityList.get(0).get("tableName");
// EntityRepository
List<EntityRepository> entityRepositoryList = collectionRepositoryService.getRepositories();
// , ,
entityRepositoryList.forEach(entityRepository -> {
// , 。
if(tableName.equals(entityRepository.getTableName())){
JpaRepository jpaRepository = entityRepository.getJpaRepository();
//
jpaRepository.save(entityModelList);
}
});
}
/**
*
* @param map
* @return
*/
private EntityModel getEntityModel(Map<String,Object> map) {
//
String tableName = (String) map.get("tableName");
//
List<EntityModel> entityList = Lists.newArrayList();
// EntityRepository
List<EntityRepository> entityRepositoryList = collectionRepositoryService.getRepositories();
entityRepositoryList.forEach(entityRepository -> {
// , 。
if(tableName.equals(entityRepository.getTableName())){
// ,
EntityFunction entityFunction = entityRepository.getEntityFunction();
EntityModel entityModel = entityFunction.convertToEntity(map);
entityList.add(entityModel);
}
});
//
return entityList.get(0);
}
/**
* ,
*/
private void copyFallback(ExecutorService executorService, ItemFeignClient ItemFeignClient, String table, String sortedField, int start, int size){
log.info("------------------------------------- !-----------------------------");
log.info(" :{}",table);
log.info("------------------------------------- !-----------------------------");
}
}
PostgreSQLService
package com.lyc.postgresql.service;
import com.lyc.postgresql.common.NumberThreads;
import com.lyc.postgresql.feign.ItemFeignClient;
import com.lyc.postgresql.sqlServer.CollectionTables;
import com.lyc.postgresql.sqlServer.tables.Tables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author: zhangzhenyi
* @date: 2019/3/28 9:11
* @description: PostgreSQL Service
**/
@Slf4j
@Service
public class PostgreSQLService {
@Autowired
ItemFeignClient itemFeignClient;
@Autowired
CopyCoreService copyCoreService;
@Autowired
NumberThreads threads;
/**
*
* @param table
* @return
*/
public int countFrom(String table) {
return itemFeignClient.countFrom(table);
}
/**
* SQLServer PostgreSQL
* @param table
* @param sortedField
* @param projectId
* @return
*/
public boolean copyFrom(String table, String sortedField, Long projectId) {
//
int total = itemFeignClient.countFrom(table);
if(total != 0){ // 0, ,
// ,
//traversePerson(total,table,sortedField);
//
traverseWithoutThreadPool(total,table,sortedField,projectId);
}
// ,
return true;
}
/**
*
* @param total
* @param table
* @param sortedField
* @param projectId
*/
private void traverseWithoutThreadPool(int total, String table, String sortedField, Long projectId) {
//
int lastCount = 0;
//
int cycleTime = Integer.valueOf(threads.getCycleTime());
//
int threadCount = 0;
// 1、 ,
if(total < cycleTime){
//
threadCount = 1;
} else { // 2、
//
lastCount = total % cycleTime;
if(lastCount == 0){ // 2.1、 = /
threadCount = total / cycleTime;
} else { // 2.2、 = / + 1
threadCount = total / cycleTime + 1;
}
}
for(int i = 1; i <= threadCount; i ++){ //
//
final int start = (i - 1) * cycleTime;
// 1、 threadCount 1
if(threadCount == 1){
//
copyCoreService.copyCore(itemFeignClient,table,sortedField,start, total, projectId);
} else { // 2、 threadCount 1
if(i < threadCount){ // 2.1、 ,
copyCoreService.copyCore(itemFeignClient,table,sortedField,start, cycleTime, projectId);
} else { // 2.2、 ,
final int size = total - start;
copyCoreService.copyCore(itemFeignClient,table,sortedField,start, size, projectId);
}
}
}
}
/**
*
* @return
*/
public boolean copy() {
// SQLServer
CollectionTables collectionTables = CollectionTables.newCollectionTables();
List<Tables> tableList = collectionTables.getTables();
// id
final Long projectId = new Date().getTime();
tableList.forEach(table -> {
// SQLServer PostgreSQL
copyFrom(table.getTableName(),table.getSortedField(),projectId);
});
return true;
}
/**
* person
* @param total
* @param sortedField
* @param table
*/
private void traversePerson(int total, String table, String sortedField){
//
int lastCount = 0;
//
int cycleTime = Integer.valueOf(threads.getCycleTime());
//
int numberThreads = Integer.valueOf(threads.getNumberThreads());
//
int threadCount = 0;
// ( ) , , ,
ExecutorService executorService = Executors.newFixedThreadPool(numberThreads);
// 1、 ,
if(total < cycleTime){
//
threadCount = 1;
} else { // 2、
//
lastCount = total % cycleTime;
if(lastCount == 0){ // 2.1、 = /
threadCount = total / cycleTime;
} else { // 2.2、 = / + 1
threadCount = total / cycleTime + 1;
}
}
for(int i = 1; i <= threadCount; i ++){ //
//
final int start = (i - 1) * cycleTime;
// 1、 threadCount 1
if(threadCount == 1){
//
copyCoreService.copyCore(executorService,itemFeignClient,table,sortedField,start, total);
} else { // 2、 threadCount 1
if(i < threadCount){ // 2.1、 ,
copyCoreService.copyCore(executorService,itemFeignClient,table,sortedField,start, cycleTime);
} else { // 2.2、 ,
final int size = total - start;
copyCoreService.copyCore(executorService,itemFeignClient,table,sortedField,start, size);
}
}
}
executorService.shutdown();
}
}
controller
PostgreSQLController
package com.lyc.postgresql.controller;
import com.lyc.postgresql.service.PostgreSQLService;
import com.lyc.postgresql.util.TimeFormatUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: zhangzhenyi
* @date: 2019/3/28 9:10
* @description: PostgreSQL Controller
**/
@RestController
public class PostgreSQLController {
@Autowired
PostgreSQLService postgreSQLService;
/**
*
* @param table
* @return
*/
@GetMapping("/countFrom/{table}")
public int countFrom(@PathVariable("table") String table){
return postgreSQLService.countFrom(table);
}
/**
*
* @return
*/
@GetMapping("/copy")
public String copy(){
TimeFormatUtil timeFormatUtil = TimeFormatUtil.newTimeFormatUtil();
//
timeFormatUtil.setStartTime();
//
boolean flag = postgreSQLService.copy();
//
timeFormatUtil.setEndTime();
//
String spendTime = timeFormatUtil.getSpendTime();
//
return flag ? " !" + spendTime : " !";
}
}
Bootstrap 시작 클래스
PostgreSQLApplication
package com.lyc.postgresql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* @author: zhangzhenyi
* @date: 2019/3/26 22:14
* @description: PostgreSQL Bootstrap
**/
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients
@EnableHystrix
public class PostgreSQLApplication {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(PostgreSQLApplication.class,args);
}
}
프로필
application.yml
spring:
application:
#
name: postgresql-server
datasource:
# spring
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/gs
username: postgres
password: root
# jpa
jpa:
show-sql: true
hibernate:
ddl-auto: update
use-new-id-generator-mappings: true
jackson:
serialization:
indent_output: false
#
server:
port: 8083
eureka:
instance:
# IP 。 Eureka
prefer-ip-address: true
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
### mybatis config ###
mybatis:
type-aliases-package: com.lyc.postgresql.entity
# Hystrix
hystrix:
command:
default:
execution:
timeout:
enabled: false
ribbon:
ReadTimeout: 120000
ConnectTimeout: 60000
application.properties
#
thread.numberTreads=10
# ,
pagequery.cycleTime=100
실행 결과
이것 의 운행 은 비교적 간단 하 므 로 아래 의 경 로 를 직접 방문 하면 된다.
http://localhost:8083/copy
데이터 의 양 이 비교적 많 기 때문에 나머지 는 옆에서 묵묵히 기다 리 는 것 이다. 가끔 콘 솔 을 주시 하고 프로젝트 데이터 이동 의 진 도 를 살 펴 보 는 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.