当前位置: 首页 > news >正文

JAVA设计模式:注解+模板+接口

1.基础组件

1.1注解类控制代码执行启动、停止、顺序

/*** @author : test* @description : 数据同步注解* @date : 2025/4/18*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SyncMeta {/*** 执行服务名称* @return*/String name() default "";/*** 是否启用** @return*/boolean isEnable() default false;/*** 顺序* @return*/int order() default 0;}

1.2数据获取基类

1.2.1数据获取基类接口(interface)

/*** @author : test* @description :* @date : 2025/4/18*/
public interface BaseDataAcquisition {  /*** 获取第三方数据*/void acquire();  
}

1.2.2数据获取基类抽象类(abstract)实现接口

import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/*** @author : test* @description :* @date : 2025/4/18*/
@Slf4j
public class BaseDataAcquisitionImpl<M extends BaseMapper<T>, T> implements BaseDataAcquisition {@Autowiredprotected M baseMapper;@Autowiredprotected SyncUrlProperties syncUrlProperties;@Resourceprotected ThirdDatabaseMapper thirdDatabaseMapper;@Overridepublic void acquire() {acquireData(DataSouceEnum.DATASOURCE);}/*** 数据来源方式*/protected void acquireData(DataSouceEnum dataSouceEnum) {List<T> allData = new ArrayList<>();switch (dataSouceEnum) {case DATASOURCE:allData = getThirdDataFromDB();break;case INTERFACE:allData = getDataFromUrl();break;default:break;}if (CollUtil.isEmpty(allData)) {log.error("采集数据为空,请确认数据采集方式");return;}//数据抽取,新增addExtraData(allData);//数据处理dealData(allData);//集合切分,数据批处理List<List<T>> parts = Lists.partition(allData, 1000);parts.stream().forEach(list -> saveOrUpdate(list));//数据抽取处理extraDeal();}/*** 用来重写** @return*/protected List<T> getThirdDataFromDB() {return null;}/*** 用来重写** @return*/protected List<T> getDataFromUrl() {return covert(null);}/*** 用来重写* 数据保存和更新* @param part*/protected void saveOrUpdate(List<T> part) {}/*** 用来重写* 数据转换* @param body*/protected List<T> covert(String body) {List<T> allData = new ArrayList<>();return allData;}/*** 用来重写* 新增抽取数据* @param allData*/protected void addExtraData(List<T> allData) {}/*** 用来重写* 数据处理* @param allData*/protected void dealData(List<T> allData) {}/*** 用来重写* 抽取数据处理* @param allData*/protected void extraDeal() {}}

2.数据抽取实现

2.1人员数据抽取示例

@Service
@SyncMeta(name = Constants.PERSON_SERVICE, isEnable = false, order = 2)
@Slf4j
public class PersonDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdPersonMapper, ThirdPerson>{/*** 三方数据获取*/@Overrideprotected List getThirdDataFromDB() {return thirdDatabaseMapper.getAllThirdPerson();}@Overrideprotected List getDataFromUrl() {String url = syncUrlProperties.getPersonUrl();String body = HttpRequest.get(url).timeout(3000)//.body(new JSONObject())  get请求发送body会报错,post请求需放开注释.execute().body();return covert(body);}@Overrideprotected void saveOrUpdate(List part) {this.baseMapper.batchSaveOrUpdate(part);}@Overrideprotected List covert(String body) {List<ThirdPerson> thirdPeople = new ArrayList<>();//todo 转换请求结果return thirdPeople;}
}

2.2组织数据抽取示例

/*** @author : test* @description :* @date : 2025/4/18*/
@Service
@SyncMeta(name = Constants.ORG_SERVICE, isEnable = false, order = 1)
@Slf4j
public class OrgDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdOrgMapper, ThirdOrg> {@Autowiredprivate ThirdRedisOrgCache thirdRedisOrgCache;/*** 数据库方式获取数据*/@Overrideprotected List<ThirdOrg> getThirdDataFromDB() {return thirdDatabaseMapper.getAllThirdOrg();}/*** url方式获取数据*/@Overrideprotected List<ThirdOrg> getDataFromUrl() {String url = syncUrlProperties.getOrgUrl();String body = HttpRequest.get(url).timeout(5000)//.body(new JSONObject())  get请求发送body会报错,post请求需放开注释.execute().body();return covert(body);}/*** 数据更新或保存*/@Overrideprotected void saveOrUpdate(List<ThirdOrg> part) {this.baseMapper.batchSaveOrUpdate(part);}/*** 数据转换*/@Overrideprotected List<ThirdOrg> covert(String body) {List<ThirdOrg> thirdOrgs = new ArrayList<>();//todo 转换请求结果return thirdOrgs;}/*** 数据新增*/@Overrideprotected void addExtraData(List<ThirdOrg> allData) {ThirdOrg thirdOrg = new ThirdOrg();thirdOrg.setName(Constants.NO_ORG_NAME_NAME);thirdOrg.setThirdCode(Constants.NO_ORG_NAME_CODE);thirdOrg.setType(0);allData.add(thirdOrg);}/*** 数据处理*/@Overrideprotected void extraDeal() {thirdRedisOrgCache.initData();}
}

2.3 mybatis 数据批量新增更新操作

<insert id="batchSaveOrUpdate">insert into third_person(NAME, CODE, SEX, PHONE, CARD_NUMBER, ID_CARD, EMAIL, ENTRY_DATE, CAR_NUMBER, THIRD_ORG_CODE, THIRD_DORM_CODE, TYPE)values<foreach collection="pojoList" item="item" index="index" separator=",">(#{item.name},#{item.code},#{item.sex},#{item.phone},#{item.cardNumber},#{item.idCard},#{item.email},#{item.entryDate},#{item.carNumber},#{item.thirdOrgCode},#{item.thirdDormCode},#{item.type})</foreach>ON DUPLICATE KEY UPDATENAME = values(NAME),SEX = values(SEX),PHONE = values(PHONE),CARD_NUMBER = values(CARD_NUMBER),EMAIL = values(EMAIL),ID_CARD = values(ID_CARD),ENTRY_DATE = values(ENTRY_DATE),THIRD_ORG_CODE = values(THIRD_ORG_CODE),THIRD_DORM_CODE = values(THIRD_DORM_CODE),TYPE = values(TYPE),UPDATE_TIME = now()</insert>

3.数据抽取触发

/**** @author : test* @description :* @date : 2025/4/18*/
@Service
public class DataAcquisitionStrategy {public void process(List<String> serviceNames) {Map<String, BaseDataAcquisition> allServiceMap = AppContextHelper.getContext().getBeansOfType(BaseDataAcquisition.class);List<BaseDataAcquisition> allAcquisitionService = allServiceMap.values().stream().collect(Collectors.toList());List<BaseDataAcquisition> processServices = allAcquisitionService.stream().filter(service -> {SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);if (CollUtil.isNotEmpty(serviceNames)) {return syncMeta != null && syncMeta.isEnable() && serviceNames.contains(syncMeta.name());} else {return syncMeta != null && syncMeta.isEnable();}}).collect(Collectors.toList());TreeMap<Integer, BaseDataAcquisition> sortedMap = new TreeMap<>();processServices.forEach(service->{SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);sortedMap.put(syncMeta.order(), service);});sortedMap.values().forEach(service-> service.acquire());}}
http://www.xdnf.cn/news/16075.html

相关文章:

  • 解锁健康生活:养生新主张
  • 【AI飞】AutoIT入门七(实战):python操控autoit解决csf视频批量转换(有点难,AI都不会)
  • 汽车行驶工况特征参数:从“速度曲线”到“驾驶DNA”的硬核解码
  • Linux:命令行参数、环境变量
  • ES6 Object.values 特定字段处理
  • IntelliJ IDEA clean git password
  • 每日一题(小白)暴力娱乐篇33
  • ObjectOutputStream 深度解析
  • 关于RK3588cpu多线程速度慢的问题
  • vLLM V1:性能优化与集群扩展的深度解析
  • LabVIEW 项目开发:需求引导与系统统筹
  • DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_自定义单元格大小示例(CalendarView01_07)
  • 基于CNN与VGG16的图像识别快速实现指南
  • 职坐标IT培训热门技术实战精讲
  • 跟我学C++中级篇——内存异常的分析
  • 在排序数组中查找元素的第一个和最后一个位置--LeetCode
  • 【SAP ME 43】RESRCE表操作导致HANA中表锁定解决方案
  • Netlink套接字
  • 基于微信小程序的中医小妙招系统的设计与实现
  • 使用dompurify修复XSS跨站脚本缺陷
  • k8s 调整Node节点 Max_Pods
  • dify本地部署,docker-plugin_daemon-1启动不了,一直报错
  • rtps报文分析
  • 2025年消防设施操作员考试题库及答案
  • Windows 11设置开机自动运行 .jar 文件
  • 实战篇|多总线网关搭建与量产验证(5000 字深度指南)
  • 第五章、SpringBoot与消息通信(一)
  • useMemo + memo + useContext 性能优化实战:从无感重渲染到丝滑体验
  • 深入理解 Android Handler
  • Rocky8 升级 Python 3.9.20 并部署 Airflow 2.10.5