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

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

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);}}

相关文章:

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

1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构&#xff1a; 这几个表总数为100多万&#xff0c;经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图&#xff1a; 界面&#xff1a; SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…...

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…...

Linux云服务器docker使用教程

诸神缄默不语-个人CSDN博文目录 我用的是腾讯云服务器&#xff0c;操作系统是OpenCloudOS 9&#xff0c;基本上可以当特色版CentOS用。 docker安装跟各个系统关系太大了&#xff0c;我就不写了。OpenCloudOS 9安装docker见这篇博文&#xff1a;腾讯云服务器使用教程 文章目录 …...

如何从android的webview 取得页面上的数据

要从Android的WebView中获取页面上的数据&#xff0c;通常有几种常见的方法&#xff1a; JavaScript Interface&#xff1a;通过JavaScript和Android Interface进行通信。这种方法允许你在JavaScript中调用Android的方法&#xff0c;反之亦然。 Evaluate JavaScript&#xff…...

VTK知识学习(12)- 读取PNG图像

1、代码 private void ShowPngImage(){vtkPNGReader pngReader vtkPNGReader.New();pngReader.SetFileName("D:\\图像\\boxes\\cardboard_boxes_01.png");pngReader.Update();vtkImageActor imageActor vtkImageActor.New();imageActor.SetInputData(pngReader.Get…...

Springboot项目搭建(3)-更改用户信息与文件上传

1.概要 前一章节完成了用户信息的注册、登录、详细信息查询&#xff0c;以及线程池与拦截器技术。 这一章完善了用户信息更新/更改功能&#xff0c;包括昵称、邮箱、头像、密码等... 而后接触到了本地上传和云上传&#xff0c;其二者区别&#xff1a; 选择本地上传还是云上…...

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析

目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …...

android 如何获取当前 Activity 的类名和包名

其一&#xff1a;getClass().getSimpleName() public static String getTopActivity(Context context){ ActivityManager am (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); ComponentName cn am.getRunningTasks(1).get(0).topAct…...

Spring Boot 项目 myblog 整理

myblog 项目是一个典型的 Spring Boot 项目&#xff0c;主要包括用户注册、登录、文章管理&#xff08;创建、查询、更新、删除&#xff09;等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包&#xff1a; Spring Boot W…...

uniapp 城市选择插件

uniapp城市选择插件 如上图 地址 完整demo <template><view><city-selectcityClick"cityClick":formatName"formatName":activeCity"activeCity":hotCity"hotCity":obtainCitys"obtainCitys":isSearch&quo…...

测试工程师如何在面试中脱颖而出

目录 1.平时工作中是怎么去测的&#xff1f; 2.B/S架构和C/S架构区别 3.B/S架构的系统从哪些点去测&#xff1f; 4.你为什么能够做测试这一行&#xff1f;&#xff08;根据个人情况分析理解&#xff09; 5.你认为测试的目的是什么&#xff1f; 6.软件测试的流程&#xff…...

Mesh路由组网

Mesh无线网格网络&#xff0c;多跳&#xff08;multi-hop&#xff09;网络&#xff0c;为解决全屋覆盖信号&#xff0c;一般用于家庭网络和小型企业 原理 网关路由器&#xff08;主路由&#xff0c;连接光猫&#xff09;&#xff0c;Mesh路由器&#xff08;子路由&#xff0c;…...

LeetCode131:分割回文串

题目链接&#xff1a;131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; class Solution { private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int s…...

详细解析 devmem 命令:在 Linux 系统中直接访问内存的利器

目录 什么是 devmem&#xff1f;为什么需要 devmem&#xff1f;devmem 命令的基本语法devmem 在硬件调试中的应用安全性与风险devmem 的常见应用示例结论 在嵌入式系统开发和硬件调试中&#xff0c;开发者经常需要直接与硬件打交道&#xff0c;访问和修改内存中某些特定区域的内…...

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…...

【前端知识】nodejs项目配置package.json深入解读

package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件&#xff0c;它位于项目的根目录下&#xff0c;并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...

XGBOOST算法Python实现(保姆级)

摘要 XGBoost算法&#xff08;eXtreme Gradient Boosting&#xff09;在目前的Kaggle、数学建模和大数据应用等竞赛中非常流行。本文将会从XGBOOST算法原理、Python实现、敏感性分析和实际应用进行详细说明。 目录 0 绪论 一、材料准备 二、算法原理 三、算法Python实现 3…...

JDK、MAVEN与IDEA的安装与配置

1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境&#xff0c;使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载&#xff1a; MAVEN下载传送…...

输出比较简介

输出比较简介 主要是用来输出PWM波形&#xff0c;这个波形是驱动电机的&#xff08;智能车和机器人等&#xff09;必要条件 OC&#xff08;Output Compare&#xff09;输出比较&#xff0c;还有IC&#xff0c;全称是Input Capture&#xff0c;意为输入捕获&#xff0c;还有CC…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...