KKSU
2025-02-05 2caf98df09bd38006ca5e590fa2418588bf0a351
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
package cc.mrbird.febs.common.utils;
 
import cc.mrbird.febs.common.exception.FebsException;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
 
/**
 * 实体验证工具类
 */
public class ValidateEntityUtils {
 
    /**
     * 确保指定列的有效性,并返回相应的实体对象
     *      selectOne方法
     *      此方法用于验证数据库中某列的值是否存在,并返回包含该值的实体对象
     *      如果指定的值不存在或为null,将抛出异常
     *
     * @param valueToCheck 需要验证的值
     * @param columnExtractor 列值提取器,用于指定需要验证的列
     * @param queryWrapperExtractor 查询包装器提取器,用于执行数据库查询
     * @param errMsg 错误消息格式字符串
     * @param columnExtractors 可变参数(varargs)查询字段,可选,如果没有就是查询全部
     * @param <T> 实体类类型
     * @param <R> 列值类型
     * @param <V> 需要验证的值的类型
     * @return 返回包含指定列值的实体对象
     * @throws IllegalArgumentException 如果需要验证的值为null
     * @throws FebsException 如果查询结果为空或列值为null,或查询过程中发生异常
     */
    public static <T, R, V> T ensureColumnReturnEntity(
            V valueToCheck,
            SFunction<T, R> columnExtractor,
            SFunction<LambdaQueryWrapper<T>, T> queryWrapperExtractor,
            String errMsg,
            SFunction<T, R>... columnExtractors) {
 
        // 检查输入参数是否为null
        if (valueToCheck == null) {
            throw new IllegalArgumentException("The value to check cannot be null while ensureColumnReturnEntity column");
        }
        if (columnExtractor == null || queryWrapperExtractor == null) {
            throw new IllegalArgumentException("Column extractor and query wrapper extractor cannot be null while ensureColumnReturnEntity column");
        }
 
        T entity = null;
        try {
            // 创建LambdaQueryWrapper并配置查询条件
            LambdaQueryWrapper<T> wrapper = Wrappers.lambdaQuery();
            if (columnExtractors != null && columnExtractors.length > 0) {
                wrapper.select(columnExtractors);
            }
            wrapper.eq(columnExtractor, valueToCheck)
                    .last("limit 1");
 
            // 执行查询并获取结果实体
            entity = queryWrapperExtractor.apply(wrapper);
 
            // 如果查询结果为空,则抛出异常
            if (entity == null) {
                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
            }
 
            // 提取查询结果中的列值
            R columnValue = columnExtractor.apply(entity);
            // 如果列值为null,则抛出异常
            if (columnValue == null) {
                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
            }
 
        } catch (FebsException e) {
            // 记录异常日志
            throw e;
        } catch (Exception e) {
            // 记录异常日志
            throw new FebsException(StrUtil.format("An error occurred while ensuring column return entity: {}", valueToCheck));
        }
 
        // 返回查询到的实体类对象
        return entity;
    }
 
    /**
     * 确保指定列的有效性,并返回相应的实体对象列表
     *      selectList方法
     *      此方法用于验证数据库中某列的值是否存在,并返回包含该值的实体对象列表
     *      如果指定的值不存在或为null,将抛出异常
     *
     * @param valueToCheck 需要验证的值
     * @param columnExtractor 列值提取器,用于指定需要验证的列
     * @param queryWrapperExtractor 查询包装器提取器,用于执行数据库查询
     * @param errMsg 错误消息格式字符串
     * @param columnExtractors 可变参数(varargs)查询字段,可选,如果没有就是查询全部
     * @param <T> 实体类类型
     * @param <R> 列值类型
     * @param <V> 需要验证的值的类型
     * @return 返回包含指定列值的实体对象列表
     * @throws IllegalArgumentException 如果需要验证的值为null
     * @throws FebsException 如果查询结果为空或列值为null,或查询过程中发生异常
     */
    public static <T, R, V> List<T> ensureColumnReturnEntityList(
            V valueToCheck,
            SFunction<T, R> columnExtractor,
            SFunction<LambdaQueryWrapper<T>, List<T>> queryWrapperExtractor,
            String errMsg,
            SFunction<T, R>... columnExtractors) {
        // 检查需要验证的值是否为null
        if (valueToCheck == null) {
            throw new IllegalArgumentException("The value to check cannot be null while ensureColumnReturnEntityList column");
        }
        List<T> entities = new ArrayList<>();
        try {
            // 创建LambdaQueryWrapper并配置查询条件
            LambdaQueryWrapper<T> wrapper = Wrappers.lambdaQuery();
            if (columnExtractors != null && columnExtractors.length > 0) {
                wrapper.select(columnExtractors);
            }
            wrapper.eq(columnExtractor, valueToCheck);
 
            // 执行查询并获取结果实体列表
            entities = queryWrapperExtractor.apply(wrapper);
        } catch (Exception e) {
            // 记录异常日志
            throw new FebsException(StrUtil.format("An error occurred while ensureColumnReturnEntityList column: {}", valueToCheck));
        }
        // 如果查询结果为空,则抛出异常
        if (entities == null || entities.isEmpty()) {
            throw new FebsException(StrUtil.format(errMsg, valueToCheck));
        }
 
        // 返回查询到的实体类对象列表
        return entities;
    }
 
    /**
     * 确保指定列的值在数据库中是存在的
     *      selectOne方法
     *      该方法通过查询数据库来验证给定的列值是否存在如果不存在,则抛出异常
     *
     * @param valueToCheck 需要验证的列值
     * @param columnExtractor 用于提取实体类中列值的函数式接口
     * @param queryWrapperExtractor 用于构建查询条件并返回实体类的函数式接口
     * @param errMsg 当列值无效时抛出的异常消息格式字符串
     * @throws IllegalArgumentException 如果需要验证的值为null
     * @throws FebsException 如果在数据库中找不到指定的列值或列值为null,或者在查询过程中发生异常
     */
    public static <T, R, V> void ensureColumnValid(
            V valueToCheck,
            SFunction<T, R> columnExtractor,
            SFunction<LambdaQueryWrapper<T>, T> queryWrapperExtractor,
            String errMsg) {
        // 检查需要验证的值是否为null
        if (valueToCheck == null) {
            throw new IllegalArgumentException("The value to check cannot be null while ensureColumnValid column");
        }
 
        try {
            // 创建LambdaQueryWrapper并配置查询条件
            LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
            wrapper.select(columnExtractor)
                    .eq(columnExtractor, valueToCheck)
                    .last("limit 1");
 
            // 执行查询并获取结果实体
            T entity = queryWrapperExtractor.apply(wrapper);
            // 如果查询结果为空,则抛出异常
            if (entity == null) {
                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
            }
 
            // 提取查询结果中的列值
            R columnValue = columnExtractor.apply(entity);
            // 如果列值为null,则抛出异常
            if (columnValue == null) {
                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
            }
        } catch (Exception e) {
            // 记录异常日志
            throw new FebsException(e.getMessage());
        }
    }
 
    /**
     * 确保指定值在数据库中是唯一的
     *      selectCount方法
     *      该方法通过查询数据库来验证给定的列值是否已经存在,如果存在,则抛出异常,以确保数据的唯一性
     *
     * @param valueToCheck 需要检查的值
     * @param columnExtractor 用于提取实体类字段的函数式接口
     * @param countWrapperExtractor 用于获取查询条件包装器中记录数的函数式接口
     * @param errMsg 错误消息模板,当值不唯一时使用
     * @param <T> 实体类类型
     * @param <R> 字段类型
     * @param <V> 需要检查的值的类型
     * @throws IllegalArgumentException 如果需要检查的值为null,则抛出此异常
     * @throws FebsException 如果值已存在或在检查过程中发生错误,则抛出此异常
     */
    public static <T, R, V> void ensureUnique(
            V valueToCheck,
            SFunction<T, R> columnExtractor,
            SFunction<LambdaQueryWrapper<T>, Integer> countWrapperExtractor,
            String errMsg) {
        // 检查输入值是否为null,如果为null,则抛出IllegalArgumentException异常
        if (valueToCheck == null) {
            throw new IllegalArgumentException("The value to check cannot be null while ensureUnique column");
        }
        if (columnExtractor == null) {
            throw new IllegalArgumentException("The columnExtractor cannot be null while ensureUnique column");
        }
        if (countWrapperExtractor == null) {
            throw new IllegalArgumentException("The countWrapperExtractor cannot be null while ensureUnique column");
        }
 
        int count = 0;
        try {
            // 创建LambdaQueryWrapper对象,用于构建查询条件
            LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
            // 添加等于条件,检查的字段=需要检查的值
            wrapper.eq(columnExtractor, valueToCheck);
            // 执行查询并获取结果数量
            count = countWrapperExtractor.apply(wrapper);
 
        } catch (Exception e) {
            // 记录异常日志
            throw new FebsException(StrUtil.format("An error occurred while ensureUnique column: {}", valueToCheck));
        }
 
        // 如果结果数量大于0,说明值已存在,抛出FebsException异常
        if (count > 0) {
            throw new FebsException(StrUtil.format(errMsg, valueToCheck));
        }
    }
 
 
    /**
     * 确保两个参数相等,如果不相等则抛出异常
     *
     * @param value1 第一个参数
     * @param value2 第二个参数
     * @param errMsg 当两个参数不相等时抛出的异常消息格式字符串
     * @throws FebsException 如果两个参数不相等
     */
    public static <T> void ensureEqual(
            T value1,
            T value2,
            String errMsg) {
        // 使用 Objects.equals 处理 null 值,避免显式 null 检查
        if (!Objects.equals(value1, value2)) {
            // 延迟字符串格式化,只在需要抛出异常时进行
            throw new FebsException(StrUtil.format(errMsg, value1, value2));
        }
    }
 
 
    /**
     * 确保两个参数不相等,如果相等则抛出异常
     *
     * @param value1 第一个参数
     * @param value2 第二个参数
     * @param errMsg 当两个参数相等时抛出的异常消息格式字符串
     * @throws FebsException 如果两个参数相等
     */
    public static <T> void ensureNotEqual(
            T value1,
            T value2,
            String errMsg) {
        // 使用 Objects.equals 处理 null 值,避免显式 null 检查
        if (Objects.equals(value1, value2)) {
            // 延迟字符串格式化,只在需要抛出异常时进行
            throw new FebsException(StrUtil.format(errMsg, value1, value2));
        }
    }
 
 
}