静态内部类的定义

@Slf4j
public class CustomizeQueryUtils {




    @Data
    public static class QueryPermission {
         /**
          * 身份
          */
         private RoleEnum role;


         /**
          * 所属门店
          */
         private Long deptIds;

         /**
          * mysql门店字段
          */
         private String deptIdFeildsName;

    }
CustomizeQueryUtils.QueryPermission permission = new CustomizeQueryUtils.QueryPermission();

Stream中 flatMap使用

List<String> saveRequestDeptList = sysMqttRequestInfoEntity.stream()
        .map(item -> item.getCompleteDeptIds())
        .flatMap(item -> Arrays.stream(item.split(",")))
        .distinct()
        .collect(Collectors.toList());

flatMap(item -> Arrays.stream(item.split(","))):将每个 completeDeptIds 按逗号分割为字符串数组,并通过 flatMap 将多个数组合并为一个流。

flatMap 是处理嵌套结构或需要将多个集合合并成一个集合时非常有用的工具。它可以让你的代码更加简洁和易读。

其他例子

List<List<String>> listOfLists = Arrays.asList(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d"),
    Arrays.asList("e", "f")
);

List<String> flattened = listOfLists.stream()
    .flatMap(List::stream)  // 将每个列表转换为流,然后合并
    .collect(Collectors.toList());

// 结果: [a, b, c, d, e, f]
 

Hutool api

时间格式化

try {
    // 使用 DateUtils.parseDate 进行严格日期解析
    Date date = DateUtils.parseDate(reserveDate, "yyyy-MM-dd");
} catch (ParseException e) {
    // 解析失败,抛出异常
    throw new ApiException("预约日期格式不正确,应为 yyyy-MM-dd 格式");
}

MySQL SQL语句的标准执行顺序


FROM子句
首先确定查询的数据源,包括表或视图
如果有JOIN操作,也会在这个阶段进行
ON子句
指定连接条件,用于筛选匹配的记录
OUTER子句
如果使用外连接(如LEFT JOIN、RIGHT JOIN),会在这个阶段添加不匹配的行
WHERE子句
对记录进行筛选,只保留满足条件的记录
GROUP BY子句
将数据按照指定列进行分组
HAVING子句
对分组后的数据进行筛选
SELECT子句
选择要返回的列,执行投影操作
DISTINCT关键字
去除重复记录
ORDER BY子句
对结果集进行排序
LIMIT/OFFSET子句
限制返回的记录数量

例子

SELECT DISTINCT m.menu_id
FROM sys_menu m 
LEFT JOIN sys_role_menu rm ON m.menu_id = rm.menu_id 
WHERE rm.role_id = ? AND m.deleted = 0 
GROUP BY m.menu_id
ORDER BY m.menu_id
LIMIT 10;

按照执行顺序,这个查询的执行过程是:
FROM sys_menu m - 从sys_menu表开始查询
LEFT JOIN sys_role_menu rm ON m.menu_id = rm.menu_id - 连接sys_role_menu表
WHERE rm.role_id = ? AND m.deleted = 0 - 筛选满足条件的记录
GROUP BY m.menu_id - 按menu_id分组
SELECT DISTINCT m.menu_id - 选择不重复的menu_id
ORDER BY m.menu_id - 按menu_id排序
LIMIT 10 - 限制返回10条记录

优化方向

在WHERE子句中尽可能早地过滤数据,减少后续处理的数据量
合理使用索引,尤其是在WHERE、ORDER BY和GROUP BY涉及的列上
避免在SELECT子句中使用复杂的表达式,除非必要
使用LIMIT时配合ORDER BY,可以提高查询效率

Supplier<T>


生产者角色:提供数据,不接收输入
方法:T get() - 返回一个 T 类型的对象
用途:用于延迟计算或按需获取值
示例:

Supplier<CompletableFuture<Boolean>> mqttTaskSupplier = () -> {

   return yangli();
};

public CompletableFuture<Boolean> yangli(){

//里面执行具体的业务逻辑

}

Consumer<T>


消费者角色:接收并处理数据,不返回值
方法:void accept(T t) - 接收一个 T 类型的对象并处理
用途:用于消费数据
 

CompletableFuture类

相关api

whenComplete() 

异步回调处理,不会阻塞当前线程

CompletableFuture<String> future = someAsyncOperation();

// 异步处理 - 不阻塞主线程
future.whenComplete((result, throwable) -> {
    System.out.println("异步回调执行,结果: " + result);
});

System.out.println("主线程继续执行 - 这条语句会先打印");

异步版本:
主线程:打印"主线程继续执行"
回调线程:打印"异步回调执行,结果: ..."

get()

CompletableFuture<String> future = someAsyncOperation();

// 同步处理 - 阻塞主线程
String result = future.get(); // 等待直到有结果
System.out.println("同步获取结果: " + result);
System.out.println("主线程继续执行 - 这条语句在结果获取后才执行");

同步版本:
等待异步操作完成
主线程:获取结果
主线程:打印"同步获取结果: ..."
主线程:打印"主线程继续执行

thenAccept 的异步特性

mqttFuture
    .thenAccept(result -> {
        handleSuccess(result, currentSendNumber);
    })
    .exceptionally(throwable -> {
        handleFailure(throwable, currentSendNumber);
        return null;
    });

Map<String, List<CardTypeDetail>> payTypeMap = new LinkedHashMap<>();
Map<String, Integer> payTotals = new LinkedHashMap<>();

for (MemCardStatisticsRawResult row : rawRows) {
    payTypeMap.computeIfAbsent(row.getPayType(), k -> new ArrayList<>())
            .add(new CardTypeDetail(row.getCardTypeName(), row.getCnt().intValue()));
    payTotals.merge(row.getPayType(), row.getCnt().intValue(), Integer::sum);
}

computeIfAbsent(key, k -> new ArrayList<>())

作用:检查 Map 中是否存在指定的 key,如果不存在就执行后面的 lambda 表达式创建一个新值并放入 Map,然后返回该 key 对应的值(无论是新创建的还是已存在的)。

payTypeMap.computeIfAbsent(row.getPayType(), k -> new ArrayList<>())
    .add(new CardTypeDetail(row.getCardTypeName(), row.getCnt().intValue()));

第一步:computeIfAbsent 检查 payTypeMap 中是否有这个支付方式
如果没有:执行 k -> new ArrayList<>() 创建一个空列表,放入 Map,返回这个空列表
如果已有:直接返回已存在的列表
第二步:在返回的列表上调用 .add() 添加新的卡种明细

 merge(key, value, Integer::sum)

作用:对 Map 中的某个 key 进行值的合并操作。

三种情况:
key 不存在:直接将 value 放入 Map
key 已存在:取出旧值,与传入的新值执行 Integer::sum(即相加),然后将结果更新回 Map
value 为 null:删除该 key(本例中不会出现)

更多推荐