增加内存详细处理、优化历史消息处理

This commit is contained in:
gaoyutao
2026-02-26 14:07:37 +08:00
parent 00d574fb5f
commit 9fdafe542d
12 changed files with 718 additions and 50 deletions
@@ -23,6 +23,8 @@ public enum MsgEnum {
tcpdump结果上报("TCPDUMP_RESULT"),
内存详情上报("MEMORY_DETAILS"),
获取最新策略("GET_POLICY"),
获取最新策略应答("GET_POLICY_RSP"),
@@ -74,6 +74,7 @@ public class RmResourceRegistrationController extends BaseController
@PostMapping("/export")
public void export(HttpServletResponse response, @RequestBody RmResourceRegistration rmResourceRegistration)
{
rmResourceRegistration.setDelFlag(0);
List<RmResourceRegistration> list = rmResourceRegistrationService.selectRmResourceRegistrationList(rmResourceRegistration);
ExcelUtil<RmResourceRegistration> util = new ExcelUtil<RmResourceRegistration>(RmResourceRegistration.class);
util.showColumn(rmResourceRegistration.getProperties());
@@ -18,6 +18,7 @@ import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.common.message.MessageQueue;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -30,15 +31,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* 时间范围重消费消费者(两阶段优化版)
* 第一阶段:并行消费并缓存所有消息
* 第二阶段:按设备顺序处理缓存的消息
*/
@Slf4j
@Component
public class TimeRangeReConsumer {
public class TimeRangeReConsumer implements DisposableBean {
@Autowired(required = false)
private MessageHistoryDataHandler messageHandler;
@@ -48,15 +43,15 @@ public class TimeRangeReConsumer {
private static final String END_TIME = "2026-02-02 12:00:00";
// 统计信息
private final AtomicLong receivedCount = new AtomicLong(0); // 已接收消息数
private final AtomicLong receivedCount = new AtomicLong(0);
private final AtomicLong skippedCount = new AtomicLong(0);
private final AtomicLong processedCount = new AtomicLong(0); // 已处理消息数
private final AtomicLong processedCount = new AtomicLong(0);
private final Map<Integer, Long> queueCurrentOffsets = new ConcurrentHashMap<>();
private final Set<Integer> completedQueues = ConcurrentHashMap.newKeySet();
// 控制是否继续消费
private AtomicBoolean shouldContinue = new AtomicBoolean(true);
private AtomicBoolean isProcessingPhase = new AtomicBoolean(false); // 第二阶段处理标记
private AtomicBoolean isProcessingPhase = new AtomicBoolean(false);
// 消息缓存:按clientId分组,按时间戳排序
private final ConcurrentHashMap<String, PriorityBlockingQueue<MessageWrapper>> messageCache =
@@ -78,8 +73,8 @@ public class TimeRangeReConsumer {
private String msgId;
private DeviceMessage message;
private MessageExt messageExt;
private long timestamp; // 从data中解析的时间戳
private long bornTimestamp; // 消息产生时间
private long timestamp;
private long bornTimestamp;
@Override
public int compareTo(MessageWrapper other) {
@@ -87,11 +82,25 @@ public class TimeRangeReConsumer {
}
}
// 添加一个标识字段
private final AtomicBoolean isRunning = new AtomicBoolean(false);
// 暴露启动方法
// 添加销毁方法
@Override
public void destroy() throws Exception {
log.info("正在关闭TimeRangeReConsumer线程池...");
if (sequentialProcessor != null && !sequentialProcessor.isShutdown()) {
sequentialProcessor.shutdown();
try {
if (!sequentialProcessor.awaitTermination(10, TimeUnit.SECONDS)) {
sequentialProcessor.shutdownNow();
}
} catch (InterruptedException e) {
sequentialProcessor.shutdownNow();
Thread.currentThread().interrupt();
}
}
log.info("TimeRangeReConsumer线程池已关闭");
}
public String startReconsumeTask(String startTime, String endTime, String namesrvAddr) {
if (isRunning.compareAndSet(false, true)) {
new Thread(() -> {
@@ -107,6 +116,7 @@ public class TimeRangeReConsumer {
}
return "已有任务正在运行";
}
public void startTimeRangeConsumer(String startTime, String endTime, String namesrvAddr) {
new Thread(() -> {
try {
@@ -118,6 +128,20 @@ public class TimeRangeReConsumer {
}
private void doReconsume(String startTime, String endTime, String namesrvAddr) throws Exception {
// 重置关键状态
shouldContinue.set(true);
isProcessingPhase.set(false);
// 清空缓存
messageCache.clear();
processingFutures.clear();
// 重置计数器
receivedCount.set(0);
skippedCount.set(0);
processedCount.set(0);
queueCurrentOffsets.clear();
completedQueues.clear();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long startTimestamp = sdf.parse(startTime).getTime();
long endTimestamp = sdf.parse(endTime).getTime();
@@ -166,7 +190,7 @@ public class TimeRangeReConsumer {
completedQueues.add(queueId);
// 检查是否所有队列都完成
if (completedQueues.size() >= 4) { // 假设有4个队列
if (completedQueues.size() >= 4) {
log.info("所有队列均已超过结束时间,第一阶段完成");
shouldContinue.set(false);
}
@@ -178,8 +202,7 @@ public class TimeRangeReConsumer {
String dataType = message.getDataType();
String clientId = message.getClientId();
// 只处理"网络上报重试"类型的消息
if(MsgEnum.网络上报重试.getValue().equals(dataType)){
if (MsgEnum.网络上报重试.getValue().equals(dataType) && !"a7948be4439e40bf09acf48164b336a9".equals(clientId)) {
receivedCount.incrementAndGet();
// 只缓存消息,不处理
@@ -272,7 +295,7 @@ public class TimeRangeReConsumer {
private long extractTimestampFromData(String data) {
try {
List<InitialBandwidthTraffic> interfaces = JsonDataParser.parseJsonData(data, InitialBandwidthTraffic.class);
if(!interfaces.isEmpty()) {
if (!interfaces.isEmpty()) {
// 时间戳转换
long timestamp = interfaces.get(0).getTimestamp();
return timestamp;
@@ -280,7 +303,7 @@ public class TimeRangeReConsumer {
} catch (Exception e) {
log.warn("解析data时间戳失败,使用默认值", e);
}
return System.currentTimeMillis(); // 解析失败使用当前时间
return System.currentTimeMillis();
}
/**
@@ -417,8 +440,6 @@ public class TimeRangeReConsumer {
} catch (Exception e) {
log.error("处理设备{}消息失败: msgId={}", clientId, wrapper.getMsgId(), e);
// 根据业务决定是否重试或跳过
// 这里选择跳过,记录错误
}
}
}
@@ -433,24 +454,30 @@ public class TimeRangeReConsumer {
}
/**
* 等待第二阶段处理完成
* 等待第二阶段处理完成 - 添加进度监控
*/
private void waitForPhase2Completion() {
log.info("等待所有设备顺序处理完成...");
// ==================== 新增:启动第二阶段进度监控 ====================
ScheduledExecutorService phase2Monitor = Executors.newSingleThreadScheduledExecutor();
phase2Monitor.scheduleAtFixedRate(() -> {
if (isProcessingPhase.get() && !processingFutures.isEmpty()) {
printPhase2Progress();
}
}, 5, 10, TimeUnit.SECONDS); // 5秒后开始,每10秒输出一次进度
CompletableFuture<Void> allFutures = CompletableFuture.allOf(
processingFutures.values().toArray(new CompletableFuture[0])
);
try {
// 等待所有任务完成
allFutures.get(2, TimeUnit.HOURS); // 最多等待2小时
allFutures.get(2, TimeUnit.HOURS);
log.info("✓ 所有设备顺序处理完成");
} catch (TimeoutException e) {
log.warn("第二阶段处理超时(2小时),强制结束");
// 可以记录未完成的任务
List<String> unfinishedDevices = new ArrayList<>();
for (Map.Entry<String, CompletableFuture<Void>> entry : processingFutures.entrySet()) {
if (!entry.getValue().isDone()) {
@@ -462,9 +489,21 @@ public class TimeRangeReConsumer {
} catch (Exception e) {
log.error("等待第二阶段处理异常", e);
} finally {
// 关闭进度监控
phase2Monitor.shutdownNow();
try {
phase2Monitor.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.warn("进度监控关闭异常", e);
Thread.currentThread().interrupt();
}
shutdownResources();
}
// 最后输出一次进度
printPhase2Progress();
// 最后统计
int remainingMessages = messageCache.values().stream()
.mapToInt(Queue::size)
@@ -477,12 +516,11 @@ public class TimeRangeReConsumer {
messageCache.clear();
}
}
/**
* 处理完成后关闭资源 - 添加状态重置
*/
private void shutdownResources() {
log.info("重消费完成,正在关闭资源...");
private void shutdownResources() {
log.info("重消费完成,正在清理资源...");
// 不要关闭线程池,只重置状态
shouldContinue.set(false);
isProcessingPhase.set(false);
isRunning.set(false);
@@ -491,28 +529,21 @@ public class TimeRangeReConsumer {
messageCache.clear();
processingFutures.clear();
// 关闭线程池
sequentialProcessor.shutdown();
try {
if (!sequentialProcessor.awaitTermination(10, TimeUnit.SECONDS)) {
sequentialProcessor.shutdownNow();
}
} catch (InterruptedException e) {
sequentialProcessor.shutdownNow();
Thread.currentThread().interrupt();
}
// 必须重置计数器和集合
// 重置计数器和集合
receivedCount.set(0);
processedCount.set(0);
skippedCount.set(0);
queueCurrentOffsets.clear();
completedQueues.clear();
log.info("✓ 重消费者资源已完全释放");
// 注意:不要关闭线程池!它会被复用
// sequentialProcessor.shutdown(); // 注释掉这行
log.info("✓ 重消费者状态已重置");
}
/**
* 查找大致的起始offset
* 查找大致的起始offset - 修复版(处理异常)
*/
private void findApproximateStartOffset(DefaultMQPushConsumer consumer, long startTimestamp) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -547,13 +578,20 @@ public class TimeRangeReConsumer {
log.info("队列{}: offset={} (范围: {}-{})",
queue.getQueueId(), offset, minOffset, maxOffset);
} else {
// 使用最小offset
long minOffset = consumer.minOffset(queue);
queueCurrentOffsets.put(queue.getQueueId(), minOffset);
log.info("队列{}: 使用最小offset={}", queue.getQueueId(), minOffset);
// 使用最小offset - 使用新方法避免过时API
try {
long minOffset = consumer.minOffset(queue);
queueCurrentOffsets.put(queue.getQueueId(), minOffset);
log.info("队列{}: 使用最小offset={}", queue.getQueueId(), minOffset);
} catch (Exception e) {
// 如果minOffset也失败,使用0作为兜底
log.warn("队列{}获取最小offset失败,使用0作为兜底: {}", queue.getQueueId(), e.getMessage());
queueCurrentOffsets.put(queue.getQueueId(), 0L);
}
}
} catch (Exception e) {
log.warn("队列{}设置offset失败: {}", queue.getQueueId(), e.getMessage());
log.warn("队列{}设置offset失败,使用0作为兜底: {}", queue.getQueueId(), e.getMessage());
queueCurrentOffsets.put(queue.getQueueId(), 0L);
}
}
@@ -0,0 +1,97 @@
package com.tongran.rocketmq.controller;
import com.tongran.common.core.utils.poi.ExcelUtil;
import com.tongran.common.core.web.controller.BaseController;
import com.tongran.common.core.web.domain.AjaxResult;
import com.tongran.common.core.web.page.PageDomain;
import com.tongran.common.core.web.page.TableDataInfo;
import com.tongran.common.log.annotation.Log;
import com.tongran.common.log.enums.BusinessType;
import com.tongran.common.security.annotation.RequiresPermissions;
import com.tongran.rocketmq.domain.InitialMemoryDetailsInfo;
import com.tongran.rocketmq.service.IInitialMemoryDetailsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 内存详细信息Controller
*
* @author gyt
* @date 2026-02-24
*/
@RestController
@RequestMapping("/initialMemoryDetailsInfo")
@RequiresPermissions("rocketmq:traffic")
public class InitialMemoryDetailsInfoController extends BaseController
{
@Autowired
private IInitialMemoryDetailsInfoService initialMemoryDetailsInfoService;
/**
* 查询内存详细信息列表
*/
@PostMapping("/list")
public TableDataInfo list(@RequestBody InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(initialMemoryDetailsInfo.getPageNum());
pageDomain.setPageSize(initialMemoryDetailsInfo.getPageSize());
startPage(pageDomain);
List<InitialMemoryDetailsInfo> list = initialMemoryDetailsInfoService.selectInitialMemoryDetailsInfoList(initialMemoryDetailsInfo);
return getDataTable(list);
}
/**
* 导出内存详细信息列表
*/
@Log(title = "内存详细信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
List<InitialMemoryDetailsInfo> list = initialMemoryDetailsInfoService.selectInitialMemoryDetailsInfoList(initialMemoryDetailsInfo);
ExcelUtil<InitialMemoryDetailsInfo> util = new ExcelUtil<InitialMemoryDetailsInfo>(InitialMemoryDetailsInfo.class);
util.exportExcel(response, list, "内存详细信息数据");
}
/**
* 获取内存详细信息详细信息
*/
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
return success(initialMemoryDetailsInfoService.selectInitialMemoryDetailsInfoById(id));
}
/**
* 新增内存详细信息
*/
@Log(title = "内存详细信息", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
return toAjax(initialMemoryDetailsInfoService.insertInitialMemoryDetailsInfo(initialMemoryDetailsInfo));
}
/**
* 修改内存详细信息
*/
@Log(title = "内存详细信息", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
return toAjax(initialMemoryDetailsInfoService.updateInitialMemoryDetailsInfo(initialMemoryDetailsInfo));
}
/**
* 删除内存详细信息
*/
@Log(title = "内存详细信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
return toAjax(initialMemoryDetailsInfoService.deleteInitialMemoryDetailsInfoByIds(ids));
}
}
@@ -0,0 +1,79 @@
package com.tongran.rocketmq.domain;
import com.tongran.common.core.annotation.Excel;
import com.tongran.common.core.web.domain.BaseEntity;
import lombok.Data;
/**
* 内存详细信息对象 initial_memory_details_info
*
* @author gyt
* @date 2026-02-24
*/
@Data
public class InitialMemoryDetailsInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键ID */
private Long id;
/** 客户端ID */
@Excel(name = "客户端ID")
private String clientId;
/** 插槽总数 */
@Excel(name = "插槽总数")
private Integer total;
/** 名称(如DIMM000 */
@Excel(name = "名称")
private String name;
/** 位置(如mainboard */
@Excel(name = "位置")
private String location;
/** 厂商(如Samsung */
@Excel(name = "厂商")
private String manufacturer;
/** 容量(MB,如32768 */
@Excel(name = "容量")
private String capacity;
/** 主频(MHz,如2133 */
@Excel(name = "主频")
private String frequency;
/** 序列号(如0x32A1EA07 */
@Excel(name = "序列号")
private String serialNumber;
/** 类型(如DDR4 */
@Excel(name = "类型")
private String type;
/** 最小电压(mV,如1200 */
@Excel(name = "最小电压")
private String minVoltage;
/** RANK列(如4 rank */
@Excel(name = "RANK列")
private String rank;
/** 位宽(如72 bit */
@Excel(name = "位宽")
private String bitWidth;
/** 技术(如Synchronous|Registered */
@Excel(name = "技术")
private String technology;
/** 部件编码(如M386A4G40DM0-CPB */
@Excel(name = "部件编码")
private String partNumber;
/** 健康状态 0配置错误 1正常*/
private String healthStatus;
}
@@ -0,0 +1,21 @@
package com.tongran.rocketmq.domain.vo;
import lombok.Data;
@Data
public class MemoryDetailsVo {
private String clientId;
private Integer total;
private String name; // 名称(如 DIMM000
private String location; // 位置(mainboard
private String manufacturer; // 厂商(Samsung
private Long capacity; // 容量(MB,如 32768
private Integer frequency; // 主频(MHz,如 2133
private String serialNumber; // 序列号(如 0x32A1EA07
private String type; // 类型(DDR4
private Integer minVoltage; // 最小电压(mV,如 1200
private String rank; // RANK(列)(如 4 rank
private String bitWidth; // 位宽(如 72 bit
private String technology; // 技术(Synchronous|Registered (B N/A
private String partNumber; // 部件编码(如 M386A4G40DM0-CPB
}
@@ -0,0 +1,17 @@
package com.tongran.rocketmq.domain.vo;
import com.tongran.rocketmq.domain.InitialMemoryDetailsInfo;
import lombok.Data;
import java.util.List;
@Data
public class MemoryVo {
private List<InitialMemoryDetailsInfo> details;
private Integer total;
private Integer timestamp;
}
@@ -147,6 +147,8 @@ public class MessageHandler {
private SendAlarmPushUtil sendAlarmPushUtil;
@Autowired
private IRmAlarmThresholdService rmAlarmThresholdService;
@Autowired
private IInitialMemoryDetailsInfoService initialMemoryDetailsInfoService;
/**
@@ -174,6 +176,28 @@ public class MessageHandler {
registerHandler(MsgEnum.macvlan状态上报.getValue(), this::handleMacvlanMessage);
registerHandler(MsgEnum.iops结果上报.getValue(), this::handleIopsResultMessage);
registerHandler(MsgEnum.tcpdump结果上报.getValue(), this::handleTcpdumpResultMessage);
registerHandler(MsgEnum.内存详情上报.getValue(), this::handleMemoryDetailsMessage);
}
private void handleMemoryDetailsMessage(DeviceMessage message) {
List<MemoryVo> memoryVoList = JsonDataParser.parseJsonData(message.getData(), MemoryVo.class);
String clientId = message.getClientId();
if(memoryVoList != null && !memoryVoList.isEmpty()){
MemoryVo memoryVo = memoryVoList.get(0);
// 时间戳转换
long timestamp = memoryVo.getTimestamp();
long millis = timestamp * 1000;
Date createTime = new Date(millis / 1000 * 1000); // 去除毫秒
List<InitialMemoryDetailsInfo> detailsVoList = memoryVo.getDetails();
if(detailsVoList != null && !detailsVoList.isEmpty()){
for (InitialMemoryDetailsInfo detailsInfo : detailsVoList) {
detailsInfo.setTotal(memoryVo.getTotal());
detailsInfo.setClientId(clientId);
detailsInfo.setCreateTime(createTime);
initialMemoryDetailsInfoService.insertInitialMemoryDetailsInfo(detailsInfo);
}
}
}
}
private void handleTcpdumpResultMessage(DeviceMessage message) {
@@ -0,0 +1,61 @@
package com.tongran.rocketmq.mapper;
import java.util.List;
import com.tongran.rocketmq.domain.InitialMemoryDetailsInfo;
/**
* 内存详细信息Mapper接口
*
* @author gyt
* @date 2026-02-24
*/
public interface InitialMemoryDetailsInfoMapper
{
/**
* 查询内存详细信息
*
* @param id 内存详细信息主键
* @return 内存详细信息
*/
public InitialMemoryDetailsInfo selectInitialMemoryDetailsInfoById(Long id);
/**
* 查询内存详细信息列表
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 内存详细信息集合
*/
public List<InitialMemoryDetailsInfo> selectInitialMemoryDetailsInfoList(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 新增内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
public int insertInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 修改内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
public int updateInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 删除内存详细信息
*
* @param id 内存详细信息主键
* @return 结果
*/
public int deleteInitialMemoryDetailsInfoById(Long id);
/**
* 批量删除内存详细信息
*
* @param ids 需要删除的数据主键集合
* @return 结果
*/
public int deleteInitialMemoryDetailsInfoByIds(Long[] ids);
}
@@ -0,0 +1,61 @@
package com.tongran.rocketmq.service;
import java.util.List;
import com.tongran.rocketmq.domain.InitialMemoryDetailsInfo;
/**
* 内存详细信息Service接口
*
* @author gyt
* @date 2026-02-24
*/
public interface IInitialMemoryDetailsInfoService
{
/**
* 查询内存详细信息
*
* @param id 内存详细信息主键
* @return 内存详细信息
*/
public InitialMemoryDetailsInfo selectInitialMemoryDetailsInfoById(Long id);
/**
* 查询内存详细信息列表
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 内存详细信息集合
*/
public List<InitialMemoryDetailsInfo> selectInitialMemoryDetailsInfoList(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 新增内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
public int insertInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 修改内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
public int updateInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo);
/**
* 批量删除内存详细信息
*
* @param ids 需要删除的内存详细信息主键集合
* @return 结果
*/
public int deleteInitialMemoryDetailsInfoByIds(Long[] ids);
/**
* 删除内存详细信息信息
*
* @param id 内存详细信息主键
* @return 结果
*/
public int deleteInitialMemoryDetailsInfoById(Long id);
}
@@ -0,0 +1,96 @@
package com.tongran.rocketmq.service.impl;
import com.tongran.common.core.utils.DateUtils;
import com.tongran.rocketmq.domain.InitialMemoryDetailsInfo;
import com.tongran.rocketmq.mapper.InitialMemoryDetailsInfoMapper;
import com.tongran.rocketmq.service.IInitialMemoryDetailsInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 内存详细信息Service业务层处理
*
* @author gyt
* @date 2026-02-24
*/
@Service
public class InitialMemoryDetailsInfoServiceImpl implements IInitialMemoryDetailsInfoService
{
@Autowired
private InitialMemoryDetailsInfoMapper initialMemoryDetailsInfoMapper;
/**
* 查询内存详细信息
*
* @param id 内存详细信息主键
* @return 内存详细信息
*/
@Override
public InitialMemoryDetailsInfo selectInitialMemoryDetailsInfoById(Long id)
{
return initialMemoryDetailsInfoMapper.selectInitialMemoryDetailsInfoById(id);
}
/**
* 查询内存详细信息列表
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 内存详细信息
*/
@Override
public List<InitialMemoryDetailsInfo> selectInitialMemoryDetailsInfoList(InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
return initialMemoryDetailsInfoMapper.selectInitialMemoryDetailsInfoList(initialMemoryDetailsInfo);
}
/**
* 新增内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
@Override
public int insertInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
return initialMemoryDetailsInfoMapper.insertInitialMemoryDetailsInfo(initialMemoryDetailsInfo);
}
/**
* 修改内存详细信息
*
* @param initialMemoryDetailsInfo 内存详细信息
* @return 结果
*/
@Override
public int updateInitialMemoryDetailsInfo(InitialMemoryDetailsInfo initialMemoryDetailsInfo)
{
initialMemoryDetailsInfo.setUpdateTime(DateUtils.getNowDate());
return initialMemoryDetailsInfoMapper.updateInitialMemoryDetailsInfo(initialMemoryDetailsInfo);
}
/**
* 批量删除内存详细信息
*
* @param ids 需要删除的内存详细信息主键
* @return 结果
*/
@Override
public int deleteInitialMemoryDetailsInfoByIds(Long[] ids)
{
return initialMemoryDetailsInfoMapper.deleteInitialMemoryDetailsInfoByIds(ids);
}
/**
* 删除内存详细信息信息
*
* @param id 内存详细信息主键
* @return 结果
*/
@Override
public int deleteInitialMemoryDetailsInfoById(Long id)
{
return initialMemoryDetailsInfoMapper.deleteInitialMemoryDetailsInfoById(id);
}
}
@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tongran.rocketmq.mapper.InitialMemoryDetailsInfoMapper">
<resultMap type="InitialMemoryDetailsInfo" id="InitialMemoryDetailsInfoResult">
<result property="id" column="id" />
<result property="clientId" column="client_id" />
<result property="total" column="total" />
<result property="name" column="name" />
<result property="location" column="location" />
<result property="manufacturer" column="manufacturer" />
<result property="capacity" column="capacity" />
<result property="frequency" column="frequency" />
<result property="serialNumber" column="serial_number" />
<result property="type" column="type" />
<result property="minVoltage" column="min_voltage" />
<result property="rank" column="rank" />
<result property="bitWidth" column="bit_width" />
<result property="technology" column="technology" />
<result property="partNumber" column="part_number" />
<!-- 新增health_status字段映射 -->
<result property="healthStatus" column="health_status" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectInitialMemoryDetailsInfoVo">
select id, client_id, total, name, location, manufacturer, capacity, frequency, serial_number, type, min_voltage, rank, bit_width, technology, part_number, health_status, create_by, create_time, update_by, update_time, remark from initial_memory_details_info
</sql>
<select id="selectInitialMemoryDetailsInfoList" parameterType="InitialMemoryDetailsInfo" resultMap="InitialMemoryDetailsInfoResult">
<include refid="selectInitialMemoryDetailsInfoVo"/>
<where>
<if test="clientId != null and clientId != ''"> and client_id = #{clientId}</if>
<if test="total != null "> and total = #{total}</if>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="location != null and location != ''"> and location = #{location}</if>
<if test="manufacturer != null and manufacturer != ''"> and manufacturer = #{manufacturer}</if>
<if test="capacity != null and capacity != ''"> and capacity = #{capacity}</if>
<if test="frequency != null and frequency != ''"> and frequency = #{frequency}</if>
<if test="serialNumber != null and serialNumber != ''"> and serial_number = #{serialNumber}</if>
<if test="type != null and type != ''"> and type = #{type}</if>
<if test="minVoltage != null and minVoltage != ''"> and min_voltage = #{minVoltage}</if>
<if test="rank != null and rank != ''"> and rank = #{rank}</if>
<if test="bitWidth != null and bitWidth != ''"> and bit_width = #{bitWidth}</if>
<if test="technology != null and technology != ''"> and technology = #{technology}</if>
<if test="partNumber != null and partNumber != ''"> and part_number = #{partNumber}</if>
<!-- 新增health_status查询条件 -->
<if test="healthStatus != null and healthStatus != ''"> and health_status = #{healthStatus}</if>
</where>
</select>
<select id="selectInitialMemoryDetailsInfoById" parameterType="Long" resultMap="InitialMemoryDetailsInfoResult">
<include refid="selectInitialMemoryDetailsInfoVo"/>
where id = #{id}
</select>
<insert id="insertInitialMemoryDetailsInfo" parameterType="InitialMemoryDetailsInfo" useGeneratedKeys="true" keyProperty="id">
insert into initial_memory_details_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="clientId != null and clientId != ''">client_id,</if>
<if test="total != null">total,</if>
<if test="name != null">name,</if>
<if test="location != null">location,</if>
<if test="manufacturer != null">manufacturer,</if>
<if test="capacity != null">capacity,</if>
<if test="frequency != null">frequency,</if>
<if test="serialNumber != null">serial_number,</if>
<if test="type != null">type,</if>
<if test="minVoltage != null">min_voltage,</if>
<if test="rank != null">rank,</if>
<if test="bitWidth != null">bit_width,</if>
<if test="technology != null">technology,</if>
<if test="partNumber != null">part_number,</if>
<!-- 新增health_status字段 -->
<if test="healthStatus != null">health_status,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="clientId != null and clientId != ''">#{clientId},</if>
<if test="total != null">#{total},</if>
<if test="name != null">#{name},</if>
<if test="location != null">#{location},</if>
<if test="manufacturer != null">#{manufacturer},</if>
<if test="capacity != null">#{capacity},</if>
<if test="frequency != null">#{frequency},</if>
<if test="serialNumber != null">#{serialNumber},</if>
<if test="type != null">#{type},</if>
<if test="minVoltage != null">#{minVoltage},</if>
<if test="rank != null">#{rank},</if>
<if test="bitWidth != null">#{bitWidth},</if>
<if test="technology != null">#{technology},</if>
<if test="partNumber != null">#{partNumber},</if>
<!-- 新增health_status字段值 -->
<if test="healthStatus != null">#{healthStatus},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
<if test="remark != null">#{remark},</if>
</trim>
on duplicate key update
<trim suffixOverrides=",">
<if test="total != null">total = values(total),</if>
<if test="name != null">name = values(name),</if>
<if test="location != null">location = values(location),</if>
<if test="manufacturer != null">manufacturer = values(manufacturer),</if>
<if test="capacity != null">capacity = values(capacity),</if>
<if test="frequency != null">frequency = values(frequency),</if>
<if test="serialNumber != null">serial_number = values(serial_number),</if>
<if test="type != null">`type` = values(`type`),</if>
<if test="minVoltage != null">min_voltage = values(min_voltage),</if>
<if test="rank != null">rank = values(rank),</if>
<if test="bitWidth != null">bit_width = values(bit_width),</if>
<if test="technology != null">technology = values(technology),</if>
<if test="partNumber != null">part_number = values(part_number),</if>
<!-- 新增health_status字段更新 -->
<if test="healthStatus != null">health_status = values(health_status),</if>
update_time = now(),
<if test="remark != null">remark = values(remark),</if>
</trim>
</insert>
<update id="updateInitialMemoryDetailsInfo" parameterType="InitialMemoryDetailsInfo">
update initial_memory_details_info
<trim prefix="SET" suffixOverrides=",">
<if test="clientId != null and clientId != ''">client_id = #{clientId},</if>
<if test="total != null">total = #{total},</if>
<if test="name != null">name = #{name},</if>
<if test="location != null">location = #{location},</if>
<if test="manufacturer != null">manufacturer = #{manufacturer},</if>
<if test="capacity != null">capacity = #{capacity},</if>
<if test="frequency != null">frequency = #{frequency},</if>
<if test="serialNumber != null">serial_number = #{serialNumber},</if>
<if test="type != null">type = #{type},</if>
<if test="minVoltage != null">min_voltage = #{minVoltage},</if>
<if test="rank != null">rank = #{rank},</if>
<if test="bitWidth != null">bit_width = #{bitWidth},</if>
<if test="technology != null">technology = #{technology},</if>
<if test="partNumber != null">part_number = #{partNumber},</if>
<!-- 新增health_status字段更新 -->
<if test="healthStatus != null">health_status = #{healthStatus},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteInitialMemoryDetailsInfoById" parameterType="Long">
delete from initial_memory_details_info where id = #{id}
</delete>
<delete id="deleteInitialMemoryDetailsInfoByIds" parameterType="String">
delete from initial_memory_details_info where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>