小鹏汽车智慧材料数据库系统项目总成数据同步

1、定时任务处理

2、提供了接口

小鹏方面提供的推送的数据表结构:

这几个表总数为100多万,经过条件筛选过滤后大概2万多条数据

小鹏的人给的示例图:

界面:

SQL:

-- 查询车型
select bmm.md_material_id, bmm.material_num, bmm.material_name, bmm.material_name_en
from bm_md_material bmm
where bmm.md_material_id in(SELECT bpa.master_part_idfrom (SELECT bpa.master_part_id, bpa.sub_part_id FROM bm_part_assembly bpa WHERE bpa.bom_type = 'PART') aINNER JOIN bm_part_assembly bpa on bpa.sub_part_id = a.master_part_id AND bpa.bom_type = 'EBOM');# 根据车型材料id(md_material_id)总成主数据
select
bpa.bm_part_assembly_id as bmPartAssemblyId,
bpa.master_part_id as master_part_id,
bpa.sub_part_id as sub_part_id,
bpa.update_date as update_date,
bpa.quantity as useNumber,
bpa.weight_tag as weight,
bpa.dev_type as developStatus,
bpa.employee_id as bomResponsibleEngineer,
bpa.suggest_sourcing as procurementType,
bpa.bom_type,
bpa.change_id,
bpae.importance_level severity,
bpae.torque as tighteningTorque,
bpae.note as connectionsCodeZhDescribe,
bpae.vehicleproject as inheritedRemodeledModels,
bmm.material_num
from bm_part_assembly bpaleft join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_idinner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_id
where (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')and is_latest = 1 -- 最新版本and active_status = 'current' -- 生效状态and bpa.update_date > '2024-07-01'
#          and bpa.master_part_id = '98535' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821and bpa.master_part_id = '23821' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
#          and bpa.master_part_id = '98532' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
#          and bpa.master_part_id = '193598' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821and bpa.master_part_id = '64332' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821   如:根据子件id:64332查询,递归去查询,直到无下级
#          and bpa.sub_part_id like '64332'and material_num = '4010809DF1-00-03'
;

Mapper和Mapper.xml

<!-- 总成主数据 --><select id="syncDataByPage" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">selectbpa.bm_part_assembly_id as syncPartAssemblyId,bpa.master_part_id as masterPartId, -- 父件id(父物料id)bpa.sub_part_id as subPartId, -- 子件id(子物料id)bpa.update_date as lastSyncUpdateDate,  -- 同步版本号bpa.quantity as useNumber, -- 用量bpa.weight_tag as weight, -- 重量bpa.dev_type as developStatus, -- 开发状态bpa.employee_id as employeeId, -- 员工id 根据这个员工id去员工表查询 责任工程师bpa.suggest_sourcing as procurementType, -- 采购类型bpa.bom_type as bomType,bpa.change_id as changeId,bpae.importance_level as severity, -- 重要度bpae.torque as tighteningTorque, -- 紧固力矩bpae.note as connectionsCodeZhDescribe, -- 连接点代码中文描述bpae.vehicleproject as inheritedRemodeledModelsfrom bm_part_assembly bpaleft join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_idinner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_idwhere (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')and is_latest = 1 -- 最新版本and active_status = 'current'<if test="lastSyncUpdateDate!='' and lastSyncUpdateDate!=null">and bpa.update_date &gt; #{lastSyncUpdateDate}</if><if test="masterPartId!='' and masterPartId!=null">and bpa.master_part_id = #{masterPartId}</if>ORDER BY bpa.update_date DESCLIMIT #{start}, #{pageSize}</select><!-- 车型数据 --><select id="selectCarData" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">select bmm.md_material_id as materielId,bmm.material_num as materielCode,bmm.material_name as materielCnName,bmm.material_name_en as materielEnNamefrom bm_md_material bmmwhere bmm.md_material_id in (SELECT bpa.master_part_id from(SELECT  bpa.master_part_id, bpa.sub_part_id FROM bm_part_assembly bpaWHERE bpa.bom_type  = 'PART') aINNER JOIN bm_part_assembly bpa on bpa.sub_part_id  = a.master_part_id AND bpa.bom_type  = 'EBOM')</select><!-- BOM责任工程师 --><select id="bomResponsibleEngineer" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">select bau.user_id userId,bau.user_name userName,bau.organization_id organizationIdfrom bm_acct_user bau where user_id = #{employeeId};</select><!-- 责任部门 --><select id="bomResponsibleDepartment" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">selectbao.id as orgId, bao.org_name as bomResponsibleDepartment, bao.org_name_en as orgNameEnfrom bm_acct_organization baowhere id = #{organizationId}</select><!--生效ECN编号--><select id="selectEcnNumberEffect" resultType="string">select bmc.change_code AS ecnNumberEffectfrom bm_md_change bmc where md_change_id = #{changeId}</select><!-- 查询已同步的最新的一条版本号 --><select id="selectLastSyncUpdateDate" resultType="java.time.LocalDateTime">select DATE_FORMAT(last_sync_update_time, '%Y-%m-%d') as last_sync_update_time from bom_assembly_material_parts order by last_sync_update_time desc limit 1;</select><!-- 根据物料id查询总成下级 --><select id="selectByMaterialId" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">select bmm.md_material_id as materielId,bmm.material_name as materielCnName,bmm.material_name_en as materielEnName,bmm.material_num as materielCodefrom  bm_md_material bmmwhere md_material_id in<foreach item="item" index="index" collection="materialIds" open="(" separator="," close=")">#{item}</foreach></select><!-- 统计车型下的总成总数 --><select id="assentlyCount" resultType="java.lang.Integer">selectcount(1)from bm_part_assembly bpaleft join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_idinner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_idwhere (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')and is_latest = 1 -- 最新版本and active_status = 'current' -- 生效状态and bpa.master_part_id = #{masterPartId}</select>
@Mapper
public interface BomAssemblyMaterialPartsMapper extends BaseMapper<BomAssemblyMaterialParts> {List<BomAssembyMaterialPartsVO> ListById(@Param("bom_id") String bomId);/*** 查询已同步的最新的一条版本号*/LocalDateTime selectLastSyncUpdateDate();/*** 分页查询总成主数据* @param start* @param pageSize* @param lastSyncUpdateDate* @return*/List<BomAssemblyVo> syncDataByPage(@Param("start") int start, @Param("pageSize") int pageSize,@Param("lastSyncUpdateDate") String lastSyncUpdateDate,@Param("masterPartId") String masterPartId);/*** 车型数据* @return*/List<BomAssemblyVo>  selectCarData();/*** BOM责任工程师* @return*/BomAssemblyVo  bomResponsibleEngineer(@Param("employeeId") String employeeId);/*** 责任部门* @return*/BomAssemblyVo  bomResponsibleDepartment(@Param("organizationId") String organizationId);/*** 生效ECN编号* @return*/String  selectEcnNumberEffect(@Param("changeId") String changeId);/*** 根据物料id查询总成下级数据* @param materialIds* @return*/List<BomAssemblyVo>  selectByMaterialId(@Param("materialIds") List<String> materialIds);/*** 统计车型下的总成总数* @param masterPartId* @return*/Integer assentlyCount(@Param("masterPartId") String masterPartId);}
/*** <p>* BOM总成材料零件表 服务实现类* </p>** @author 袁腾飞* @since 2024-10-14*/
@Slf4j
@Service
public class BomAssemblyMaterialPartsServiceImpl extends ServiceImpl<BomAssemblyMaterialPartsMapper, BomAssemblyMaterialParts> implements BomAssemblyMaterialPartsService {@Autowiredprivate BomAssemblyMaterialPartsMapper bomAssemblyMaterialPartsMapper;@Autowiredprivate BomCategoryService bomCategoryService;
@Overridepublic List<BomAssemblyMaterialParts> syncDataByPage(int pageSize) {// 获取上一次同步数据的更新时间LocalDateTime lastSyncUpdateDate = selectLastSyncUpdateDate();String formatLastSyncUpdateDate = lastSyncUpdateDate==null ? "" : lastSyncUpdateDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));// 组装数据List<BomAssemblyDto> bomAssemblyDtos = assemblingData(pageSize, formatLastSyncUpdateDate);// 把组装后的数据转换为BomAssemblyMaterialParts对象// bomAssemblyDtos在里面取出每个字段// bomAssemblyDtos的父级,给BomAssemblyMaterialParts对象父级设置parentId为0,id自动生成;里层的children的parentId为外层的id// 父级的parentId设为0List<BomAssemblyMaterialParts> partsList = convertToBomAssemblyMaterialParts(bomAssemblyDtos, "0");// partsList里面的children取出与父节点一起保存if (!partsList.isEmpty()) {bomAssemblyMaterialPartSaveBatch(partsList);}return partsList;}private void bomAssemblyMaterialPartSaveBatch(List<BomAssemblyMaterialParts> partsList) {// 收集所有需要保存的节点List<BomAssemblyMaterialParts> allNodes = collectAllNodes(partsList);// 批量插入所有节点// 判断allNodes里面的syncPartAssemblyId是否在数据库中存在,如果不存在,则插入,如果存在,则更新// List<String> list = allNodes.stream().map(BomAssemblyMaterialParts::getSyncPartAssemblyId).collect(Collectors.toList());allNodes.stream().map(item -> item).forEach(item -> {// 判断item是否在数据库中存在LambdaQueryWrapper<BomAssemblyMaterialParts> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(BomAssemblyMaterialParts::getSyncPartAssemblyId, item.getSyncPartAssemblyId());BomAssemblyMaterialParts bomAssemblyMaterialParts = bomAssemblyMaterialPartsMapper.selectOne(queryWrapper);if (bomAssemblyMaterialParts == null) {// 不存在,则插入bomAssemblyMaterialPartsMapper.insert(item);} else {// 存在,则更新bomAssemblyMaterialPartsMapper.update(item, queryWrapper);}});// bomAssemblyMaterialPartsMapper.insertOrUpdate(allNodes);}private List<BomAssemblyMaterialParts> collectAllNodes(List<BomAssemblyMaterialParts> nodes) {List<BomAssemblyMaterialParts> allNodes = new ArrayList<>();for (BomAssemblyMaterialParts node : nodes) {allNodes.add(node);if (node.getChildren() != null && !node.getChildren().isEmpty()) {allNodes.addAll(collectAllNodes(node.getChildren()));}}return allNodes;}private List<BomAssemblyDto> convertToBomAssemblyDtos(List<BomAssemblyVo> bomAssemblyVos, String ecnNumberEffect) {if (bomAssemblyVos == null || bomAssemblyVos.isEmpty()) {return Collections.emptyList();}return bomAssemblyVos.stream().map(vo -> {BomAssemblyDto dto = new BomAssemblyDto();BeanUtils.copyProperties(vo, dto);dto.setChildren(convertToBomAssemblyDtos(vo.getChildren(), ecnNumberEffect));return dto;}).collect(Collectors.toList());}private List<BomAssemblyMaterialParts> convertToBomAssemblyMaterialParts(List<BomAssemblyDto> dtos, String parentId) {List<BomAssemblyMaterialParts> collect = dtos.stream().map(dto -> {String id = "";// 判断item是否在数据库中存在LambdaQueryWrapper<BomAssemblyMaterialParts> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(BomAssemblyMaterialParts::getSyncPartAssemblyId, dto.getSyncPartAssemblyId());BomAssemblyMaterialParts bomAssemblyMaterialParts = bomAssemblyMaterialPartsMapper.selectOne(queryWrapper);if (bomAssemblyMaterialParts == null) {// 不存在,则就生成idid = IdUtil.simpleUUID();} else {// 存在,id 和 parentId 保持不变id = bomAssemblyMaterialParts.getId();}BomAssemblyMaterialParts parts = new BomAssemblyMaterialParts();String bomCategoryId = dto.getBomCategoryId();BeanUtils.copyProperties(dto, parts);parts.setId(id);parts.setParentId(parentId);parts.setBomId(bomCategoryId);List<BomAssemblyDto> children = dto.getChildren();if (!children.isEmpty()) {List<BomAssemblyMaterialParts> partsList = convertToBomAssemblyMaterialParts(dto.getChildren(), parts.getId());// 这里的partList里面的数据bomId没有给赋值,需要给bomId赋值:bomCategoryId// parts.setBomId(bomCategoryId);partsList.forEach(part -> part.setBomId(bomCategoryId));parts.setChildren(partsList);}parts.setLastSyncUpdateTime(dto.getLastSyncUpdateDate());parts.setCreateTime(LocalDateTime.now());parts.setUpdateTime(LocalDateTime.now());return parts;}).collect(Collectors.toList());return collect;}/*** 组装数据** @param pageSize          每页大小* @param lastSyncVersionNo 上一次同步的版本号* @return*/private List<BomAssemblyDto> assemblingData(int pageSize, String lastSyncVersionNo) {// 先查询车型List<BomAssemblyVo> selectedCarData = selectCarData();// todo 暂时过滤一下数据,只查询一个车型// List<BomAssemblyVo> collect = selectedCarData.stream().filter(bomAssemblyVo -> bomAssemblyVo.getMaterielId().equals("23821")).collect(Collectors.toList());// 构建 md_material_id 到 BomAssemblyVo 的映射Map<String, BomAssemblyVo> carDataMap = selectedCarData.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));// Map<String, BomAssemblyVo> carDataMap = collect.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));/*步骤:1、先是查询出基础总成数据2、先查询车型,拿到车型的md_material_id3、根据拿到每个车型的md_material_id 查询 bm_part_assembly表的master_part_id,就得到了得到sub_part_id4、得到sub_part_id 查询bm_md_material表,得到了下级总成,循环类推,递归5、查询的下级放在BomAssemblyVo里面的children集合里面6、拼装数据,把查询生效ECN编号、数据量很大,100多万数据能不能用stream流、递归、树形结构select bmm.md_material_id as materialId, bmm.material_name materielName, bmm.material_num from  bm_md_material bmmwhere md_material_id in #{materialId}*/List<BomAssemblyDto> result = new ArrayList<>();// 用carDataMap key查询数据carDataMap.forEach((masterPartId, value) -> {// 获取总数Integer totalCount = assentlyCount(masterPartId);double totalPage = Math.ceil((double) totalCount / pageSize);// 分页处理for (int currentPage = 0; currentPage < totalPage; currentPage++) {int offset = currentPage * pageSize;// 根据查询的车型的id的这个key查询获取sub_part_id,在这里bomAssemblyVos获取sub_part_id值,获得sub_part_id值后再次用bomAssemblyMaterialPartsMapper.syncDataByPage查询,把查询到的sub_part_id值传入到key的位置,直到查询不到数据// 第一次查询的是父节点,递归出来的后面的查询是子节点放在children里面List<BomAssemblyVo> bomAssemblyVos = bomAssemblyMaterialPartsMapper.syncDataByPage(offset, pageSize, lastSyncVersionNo, masterPartId);// todo 临时测试用// List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("64332")).collect(Collectors.toList());// List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("98535")).collect(Collectors.toList());// List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("64332")).collect(Collectors.toList());// BOM分类车型数据LambdaQueryWrapper<BomCategory> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(BomCategory::getIsCar, 1);List<BomCategory> bomCategories = bomCategoryService.list(queryWrapper);// 车型名称String carType = value.getMaterielCnName();// 在这里获取所有的分类名称(categoryName)和id,如果categoryName与carType比较,// 如果匹配上就把bomCategories的id给BomAssemblyVo对象的bomCategoryId并保存数据,否则就不保存数据// 查找匹配的车型分类Optional<BomCategory> categoryOptional = bomCategories.stream().filter(cat -> cat.getCategoryName().equals(carType)).findFirst();if (categoryOptional.isPresent()) {String categoryId = categoryOptional.get().getId();// 设置categoryId到每个BomAssemblyVo对象setCategoryIdRecursively(bomAssemblyVos, categoryId);} else {// 如果没有匹配的分类,则跳过这些数据return;}// 补充 materialName 和 materialNum 对于父节点Set<String> parentIds = bomAssemblyVos.stream().map(BomAssemblyVo::getSubPartId).filter(Objects::nonNull).collect(Collectors.toSet());if (!parentIds.isEmpty()) {List<BomAssemblyVo> parentDetails = selectByMaterialIds(new ArrayList<>(parentIds));Map<String, BomAssemblyVo> parentDetailMap = parentDetails.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));for (BomAssemblyVo assembly : bomAssemblyVos) {BomAssemblyVo detail = parentDetailMap.get(assembly.getSubPartId());if (detail != null) {assembly.setMaterielCnName(detail.getMaterielCnName());assembly.setMaterielEnName(detail.getMaterielEnName());assembly.setMaterielCode(detail.getMaterielCode());assembly.setPartCode(detail.getPartCode());assembly.setCarType(detail.getCarType());assembly.setEcnNumberEffect(detail.getEcnNumberEffect());assembly.setPartNumber(detail.getPartNumber());assembly.setBomType(detail.getBomType());}}}// 再组装数据for (BomAssemblyVo assembly : bomAssemblyVos) {buildTree(assembly, offset, pageSize, lastSyncVersionNo);String changeId = assembly.getChangeId();String changeCode = selectEcnNumberEffect(changeId);String employeeId = assembly.getEmployeeId();String userName = "";String organizationId = "";if (StringUtils.isNotBlank(employeeId)) {// BOM责任工程师BomAssemblyVo bomAssemblyVo = bomResponsibleEngineer(employeeId);if (bomAssemblyVo != null) {userName = bomAssemblyVo.getUserName();organizationId = bomAssemblyVo.getOrganizationId();}}String bomResponsibleDepartment = "";if (StringUtils.isNotBlank(organizationId)) {// BOM责任部门BomAssemblyVo assemblyVo = bomResponsibleDepartment(organizationId);if (assemblyVo != null) {bomResponsibleDepartment = assemblyVo.getBomResponsibleDepartment();}}assembly.setUserName(userName);assembly.setBomResponsibleDepartment(bomResponsibleDepartment);BomAssemblyDto bomAssemblyDto = new BomAssemblyDto();BeanUtils.copyProperties(assembly, bomAssemblyDto);bomAssemblyDto.setChildren(convertToBomAssemblyDtos(assembly.getChildren(), changeCode));result.add(bomAssemblyDto);}}});log.info("result:::::::::" + result);// 拼装数据,包括生效ECN编号等信息// convertToBomAssemblyMaterialParts(result);return result;}private void setCategoryIdRecursively(List<BomAssemblyVo> bomAssemblyVos, String categoryId) {for (BomAssemblyVo assembly : bomAssemblyVos) {assembly.setBomCategoryId(categoryId);if (assembly.getChildren() != null && !assembly.getChildren().isEmpty()) {setCategoryIdRecursively(assembly.getChildren(), categoryId);}}}private void buildTree(BomAssemblyVo parent, int pageNo, int pageSize, String lastSyncVersionNo) {if (parent == null || parent.getSubPartId() == null) {return;}List<BomAssemblyVo> children = bomAssemblyMaterialPartsMapper.syncDataByPage(pageNo, pageSize, lastSyncVersionNo, parent.getSubPartId());// 补充 materialName 和 materialNumSet<String> subPartIds = children.stream().map(BomAssemblyVo::getSubPartId).filter(Objects::nonNull).collect(Collectors.toSet());if (!subPartIds.isEmpty()) {List<BomAssemblyVo> materialDetails = selectByMaterialIds(new ArrayList<>(subPartIds));Map<String, BomAssemblyVo> materialDetailMap = materialDetails.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));for (BomAssemblyVo child : children) {BomAssemblyVo detail = materialDetailMap.get(child.getSubPartId());if (detail != null) {child.setMaterielCnName(detail.getMaterielCnName());child.setMaterielEnName(detail.getMaterielEnName());child.setMaterielCode(detail.getMaterielCode());child.setPartCode(detail.getPartCode());child.setCarType(detail.getCarType());child.setEcnNumberEffect(detail.getEcnNumberEffect());child.setPartNumber(detail.getPartNumber());child.setBomType(detail.getBomType());}}}parent.setChildren(children);for (BomAssemblyVo child : children) {buildTree(child, pageNo, pageSize, lastSyncVersionNo);}}/*** 查询车型** @return*/private List<BomAssemblyVo> selectCarData() {List<BomAssemblyVo> list = bomAssemblyMaterialPartsMapper.selectCarData();return list;}/*** 查询生效ECN编号** @return*/private String selectEcnNumberEffect(String changeId) {return bomAssemblyMaterialPartsMapper.selectEcnNumberEffect(changeId);}/*** 根据物料id查询总成下级数据** @param materialIds* @return*/private List<BomAssemblyVo> selectByMaterialIds(List<String> materialIds) {/*这个sql是这样的:select bmm.md_material_id as materialId, bmm.material_name materielName, bmm.material_num from  bm_md_material bmmwhere md_material_id in #{materialIds}*/if (materialIds == null || materialIds.isEmpty()) {return Collections.emptyList();}return bomAssemblyMaterialPartsMapper.selectByMaterialId(materialIds);}/*** BOM责任工程师** @return*/private BomAssemblyVo bomResponsibleEngineer(String employeeId) {return bomAssemblyMaterialPartsMapper.bomResponsibleEngineer(employeeId);}/*** BOM责任部门** @param organizationId* @return*/private BomAssemblyVo bomResponsibleDepartment(String organizationId) {return bomAssemblyMaterialPartsMapper.bomResponsibleDepartment(organizationId);}/*** 同步版本号** @return*/private LocalDateTime selectLastSyncUpdateDate() {LocalDateTime lastSyncUpdateDate = bomAssemblyMaterialPartsMapper.selectLastSyncUpdateDate();log.info("最新版本号:{}", lastSyncUpdateDate);return lastSyncUpdateDate;}@Overridepublic Integer assentlyCount(String masterPartId) {Integer assentlyCount = bomAssemblyMaterialPartsMapper.assentlyCount(masterPartId);return assentlyCount == null ? 0 : assentlyCount;}}
/*** <p>* BOM总成材料零件表 服务类* </p>** @author 袁腾飞* @since 2024-10-14*/
public interface BomAssemblyMaterialPartsService extends IService<BomAssemblyMaterialParts> {IPage<BomAssemblyMaterialParts> pageListCondition(PagingQuery pagingQuery, BomAssemblyQuery queryParam);List<BomAssembyMaterialPartsVO> ListById(String bomId);List<BomAssemblyMaterialParts> listCondition(PagingQuery pagingQuery, BomAssemblyQuery queryParam);List<BomAssemblyMaterialParts> syncDataByPage(int pageSize);Integer assentlyCount(String masterPartId);
}

定时任务层

/*** 同步总成数据*/
@Slf4j
@Lazy(value = false)
@Component
// @PropertySource(value = "classpath:jobTask.properties",encoding = "UTF-8")
public class SyncWholeData {@Autowiredprivate BomAssemblyMaterialPartsService bomAssemblyMaterialPartsService;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Value("${pageSize}")private Integer pageSize;/*** 同步总成数据*/@Transactional(rollbackFor = Exception.class)@Async@Scheduled(cron = "${inactiveaccountCron}")public void syncWhole1() {String lockKey = "lock:sync:whole:";boolean isLocked = tryLock(lockKey);try {if (isLocked) {// 成功获取锁,执行同步逻辑bomAssemblyMaterialPartsService.syncDataByPage(pageSize);}} finally {unlock(lockKey);}}/*** 尝试获取锁** @param key* @return*/private boolean tryLock(String key) {// setIfAbsent 如果存在Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 2, TimeUnit.HOURS);return BooleanUtil.isTrue(flag);}/*** 释放锁** @param key*/private void unlock(String key) {stringRedisTemplate.delete(key);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476859.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式硬件实战基础篇(二)-稳定输出3.3V的太阳能电池-无限充放电

引言&#xff1a;本内容主要用作于学习巩固嵌入式硬件内容知识&#xff0c;用于想提升下述能力&#xff0c;针对学习稳压芯片和电容以及电池之间的运用&#xff0c;对于硬件PCB以及原理图的练习和前面硬件篇的实际运用&#xff1b;太阳能是一种清洁、可再生的能源&#xff0c;广…

【海思Hi3519DV500】双目网络相机套板硬件规划方案

Hi3519DV500双目网络相机套板是针对该芯片设计的一款 IP 编码板 PCBA&#xff0c;硬件接口支持双目sensor 接入&#xff0c;SDIO3.0 接口、USB2.0、USB3.0、UART 接口以及丰富的 IO 扩展应用&#xff0c;可根据各种使用场景设计相应扩展板&#xff0c;丰富外围接口&#xff0c;…

淘宝商品评论爬虫:Java实现指南

在当今的互联网时代&#xff0c;数据的价值日益凸显&#xff0c;尤其是用户生成的内容&#xff0c;如商品评论&#xff0c;对于理解消费者行为和市场趋势具有重要意义。淘宝作为中国最大的电商平台之一&#xff0c;拥有海量的商品评论数据。本文将介绍如何使用Java编写一个简单…

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中&#xff0c;校运会不仅是…

tensorflow案例7--数据增强与测试集, 训练集, 验证集的构建

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 这次主要是学习数据增强, 训练集 验证集 测试集的构建等等的基本方法, 数据集还是用的上一篇的猫狗识别;基础篇还剩下几个, 后面的难度会逐步提升;欢迎…

SpringBoot多环境+docker集成企业微信会话存档sdk

SpringBoot多环境docker集成企业微信会话存档sdk 文章来自于 https://developer.work.weixin.qq.com/community/article/detail?content_id16529801754907176021 SpringBoot多环境docker集成企业微信会话存档sdk 对于现在基本流行的springboot环境&#xff0c;官方文档真是比…

VSCode快速生成vue组件模版

1&#xff0c;点击设置&#xff0c;找到代码片段 2&#xff0c;搜索vue&#xff0c;打开vue.json 3&#xff0c;添加模版 vue2模板 "vue2": {"prefix": "vue2","body": ["<template>"," <div>$0</di…

【爬虫】Firecrawl对京东热卖网信息爬取(仅供学习)

项目地址 GitHub - mendableai/firecrawl: &#x1f525; Turn entire websites into LLM-ready markdown or structured data. Scrape, crawl and extract with a single API. Firecrawl更多是使用在LLM大模型知识库的构建&#xff0c;是大模型数据准备中的一环&#xff08;在…

VXLAN说明

1. 什么是 VXLAN &#xff1f; VXLAN&#xff08;Virtual Extensible LAN&#xff0c;虚拟扩展局域网&#xff09;是一种网络虚拟化技术&#xff0c;旨在通过在现有的物理网络上实现虚拟网络扩展&#xff0c;从而克服传统 VLAN 的一些限制。 VXLAN 主要用于数据中心、云计算环…

RTL8211F 1000M以太网PHY指示灯

在RK3562 Linux5.10 SDK里面已支持该芯片kernel-5.10/drivers/net/phy/realtek.c&#xff0c;而默认是没有去修改到LED配置的&#xff0c;我们根据硬件设计修改相应的寄存器配置&#xff0c;该PHY有3个LED引脚&#xff0c;我们LED0不使用&#xff0c;LED1接绿灯&#xff08;数据…

主IP地址与从IP地址:深入解析与应用探讨

在互联网的浩瀚世界中&#xff0c;每台联网设备都需要一个独特的身份标识——IP地址。随着网络技术的不断发展&#xff0c;IP地址的角色日益重要&#xff0c;而“主IP地址”与“从IP地址”的概念也逐渐进入人们的视野。这两个术语虽然看似简单&#xff0c;实则蕴含着丰富的网络…

【Redis】基于Redis实现秒杀功能

业务的流程大概就是&#xff0c;先判断优惠卷是否过期&#xff0c;然后判断是否有库存&#xff0c;最好进行扣减库存&#xff0c;加入全局唯一id&#xff0c;然后生成订单。 一、超卖问题 真是的场景下可能会有超卖问题&#xff0c;比如开200个线程进行抢购&#xff0c;抢100个…

计算机网络socket编程(4)_TCP socket API 详解

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(4)_TCP socket API 详解 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&…

Jmeter数据库压测之达梦数据库的配置方法

目录 1、概述 2、测试环境 3、数据库压测配置 3.1 安装jmeter 3.2 选择语言 3.3 新建测试计划 3.4 配置JDBC连接池 3.5 配置线程组 3.6 配置测试报告 3.7 执行测试 1、概述 Jmeter是Apache组织开发的基于Java的压力测试工具&#xff0c;用于对软件做压力测试。 它最…

RAG与微调:大模型落地的最佳路径选择(文末赠书)

一、大模型技术发展现状 自2022年底ChatGPT掀起AI革命以来&#xff0c;大语言模型&#xff08;LLM&#xff09;技术快速迭代发展&#xff0c;从GPT-4到Claude 2&#xff0c;从文心一言到通义千问&#xff0c;大模型技术以惊人的速度发展。然而&#xff0c;在企业实际应用场景中…

Web 入门

HTTP 一、概念 Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 二、特点 基于TCP协议&#xff1a;面向连接&#xff0c;安全。基于请求-响应模型的&#xff1a;一次请求对应一次响应。HTTP协议是无状态的协…

pinia是什么?pinia简介快速入门,创建pinia到vue3项目中

一&#xff0c;pinia就是Vuex&#xff0c;的替代工具&#xff0c;Vuex plus 如何将pinia引入到vue3项目中&#xff1f; 1.首先新建一个vue3项目 全填yes npm init vuelatest 2.安装好之后查阅官方文档 pinia使用文档 3.从而得知在项目中有俩种方式安装pinia 我的本地只有nod…

Java 基于SpringBoot+vue框架的老年医疗保健网站

大家好&#xff0c;我是Java徐师兄&#xff0c;今天为大家带来的是Java Java 基于SpringBootvue框架的老年医疗保健网站。该系统采用 Java 语言开发&#xff0c;SpringBoot 框架&#xff0c;MySql 作为数据库&#xff0c;系统功能完善 &#xff0c;实用性强 &#xff0c;可供大…

FPGA实现串口升级及MultiBoot(九)BPI FLASH相关实例演示

本文目录索引 区别一:启动流程的区别区别二:高位地址处理区别三:地址映射例程说明总结例程地址之前一直都是以SPI FLASH为例进行相关知识讲解,今天我们介绍另一款常用的配置FLASH-BPI FLASH。 今天的讲解以简洁为主,主打个能用一句话不说两句话。以和SPI区别为主,实例演…

VisionPro 机器视觉案例 之 彩色保险丝个数统计

第十四篇 机器视觉案例 之 彩色保险丝颜色识别个数统计 文章目录 第十四篇 机器视觉案例 之 彩色保险丝颜色识别个数统计1.案例要求2.实现思路2.1 方法一 颜色分离工具CogColorSegmenterTool将每一种颜色分离出来&#xff0c;得到对应的单独图像&#xff0c;使用斑点工具CogBlo…