优化:优化成员变量相关注释及部分操作写法

成员变量有时候会被称为 Field 有时候会被称为 Property,它们的区别如下:
1.Field:Field 是 Java 反射中描述类的属性信息的类。成员变量(Instance Variable)就是定义的字段(Field),例如 private String name;。Field 可以获取当前对象的成员变量的类型,对成员变量重新设值等。使用 Field 可以直接操作类的属性,不需要通过 getter 和 setter 方法,但是需要了解反射机制。
2.Property:Property 是成员变量的 getter 和 setter 方法。例如,public String getName() { return name; } 和 public void setName(String name) { this.name = name; } 分别是获取和设置 MyField 类中的实例变量 name 的 getter 和 setter 方法。使用 Property 可以在类的外部访问和修改类的属性,但是需要注意访问权限和数据类型的正确性。
综上所述,Field 和 Property 都可以用来表示 Java 类中的成员变量,选择哪种方式取决于具体的应用场景和需求。如果需要直接操作类的属性,可以使用 Field;如果需要在类的外部访问和修改类的属性,可以使用 Property。
个人理解:从 MyBatis 的映射角度来说,column 表示数据库表列/字段,property 表示 Java 对象属性/字段,所以此前在涉及到 MyBatis 操作时,尽可能多的用了 Property 而不是 Field。但除了 MyBatis 之外还有很多地方也需要用到成员变量,与其纠结 Field 还是 Property,那就用 Field,简单粗暴一点。
This commit is contained in:
Charles7c 2023-03-05 12:59:10 +08:00
parent 44fa7266b6
commit 39f267699a
9 changed files with 68 additions and 57 deletions

View File

@ -18,9 +18,7 @@ package top.charles7c.cnadmin.common.base;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@ -42,6 +40,7 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
@ -127,11 +126,9 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext
tree.setName(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.nameKey())));
tree.setWeight(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.weightKey())));
if (!isSimple) {
Field[] fieldArr = ReflectUtils.getNonStaticFields(voClass);
List<Field> fieldList = Arrays.stream(fieldArr)
.filter(f -> !StrUtil.containsAnyIgnoreCase(f.getName(), treeField.value(), treeField.parentIdKey(),
treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()))
.collect(Collectors.toList());
List<Field> fieldList = ReflectUtils.getNonStaticFields(voClass);
fieldList.removeIf(f -> StrUtil.containsAnyIgnoreCase(f.getName(), treeField.value(),
treeField.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()));
fieldList
.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, StrUtil.genGetter(f.getName()))));
}
@ -220,7 +217,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext
*/
protected T getById(Object id) {
T entity = baseMapper.selectById(Convert.toStr(id));
CheckUtils.throwIfNull(entity, String.format("ID为 [%s] 的记录已不存在", id));
CheckUtils.throwIfNull(entity, ClassUtil.getClassName(entityClass, true), "ID", id);
return entity;
}

View File

@ -110,16 +110,16 @@ public class MyBatisPlusMetaObjectHandler implements MetaObjectHandler {
}
/**
* 填充属性
* 填充字段
*
* @param metaObject
* 元数据对象
* @param fieldName
* 要填充的属性
* 要填充的字段
* @param fillFieldValue
* 要填充的属性
* 要填充的字段
* @param isOverride
* 如果属性值不为空是否覆盖true 覆盖false 不覆盖
* 如果字段值不为空是否覆盖true 覆盖false 不覆盖
*/
private void fillFieldValue(MetaObject metaObject, String fieldName, Object fillFieldValue, boolean isOverride) {
if (metaObject.hasSetter(fieldName)) {

View File

@ -19,6 +19,8 @@ package top.charles7c.cnadmin.common.util;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
@ -44,9 +46,9 @@ public class ReflectUtils {
* @throws SecurityException
* 安全检查异常
*/
public static String[] getNonStaticFieldsName(Class<?> beanClass) throws SecurityException {
Field[] nonStaticFields = getNonStaticFields(beanClass);
return Arrays.stream(nonStaticFields).map(Field::getName).toArray(String[]::new);
public static List<String> getNonStaticFieldsName(Class<?> beanClass) throws SecurityException {
List<Field> nonStaticFields = getNonStaticFields(beanClass);
return nonStaticFields.stream().map(Field::getName).collect(Collectors.toList());
}
/**
@ -59,8 +61,8 @@ public class ReflectUtils {
* @throws SecurityException
* 安全检查异常
*/
public static Field[] getNonStaticFields(Class<?> beanClass) throws SecurityException {
public static List<Field> getNonStaticFields(Class<?> beanClass) throws SecurityException {
Field[] fields = ReflectUtil.getFields(beanClass);
return Arrays.stream(fields).filter(f -> !Modifier.isStatic(f.getModifiers())).toArray(Field[]::new);
return Arrays.stream(fields).filter(f -> !Modifier.isStatic(f.getModifiers())).collect(Collectors.toList());
}
}

View File

@ -41,7 +41,7 @@ import top.charles7c.cnadmin.common.util.validate.CheckUtils;
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TreeUtils {
/** 默认属性配置对象(根据前端树结构灵活调整名称) */
/** 默认字段配置对象(根据前端树结构灵活调整名称) */
public static final TreeNodeConfig DEFAULT_CONFIG =
TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title").setIdKey("key").setWeightKey("sort");

View File

@ -18,7 +18,6 @@ package top.charles7c.cnadmin.common.util.helper;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.AccessLevel;
@ -32,6 +31,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import top.charles7c.cnadmin.common.annotation.Query;
import top.charles7c.cnadmin.common.util.ReflectUtils;
/**
* 查询助手
@ -61,38 +61,19 @@ public class QueryHelper {
return queryWrapper;
}
// 获取查询条件中所有的属性包括私有的和父类的
List<Field> fieldList = getFieldList(query.getClass(), new ArrayList<>());
// 获取查询条件中所有的字段
List<Field> fieldList = ReflectUtils.getNonStaticFields(query.getClass());
fieldList.forEach(field -> buildQuery(query, field, queryWrapper));
return queryWrapper;
}
/**
* 获取指定类型的所有属性包括私有的和父类的
*
* @param clazz
* 指定类型
* @param fieldList
* 属性列表
* @param <Q>
* 查询条件数据类型
* @return 属性列表包括私有的和父类的
*/
public static <Q> List<Field> getFieldList(Class<Q> clazz, List<Field> fieldList) {
if (clazz != null) {
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
getFieldList(clazz.getSuperclass(), fieldList);
}
return fieldList;
}
/**
* 构建 MyBatis Plus 查询条件封装对象
*
* @param query
* 查询条件
* @param field
* 属性
* 字段
* @param queryWrapper
* MyBatis Plus 查询条件封装对象
* @param <Q>
@ -110,7 +91,7 @@ public class QueryHelper {
return;
}
// 如果属性值为空直接返回
// 如果字段值为空直接返回
Object fieldValue = field.get(query);
if (ObjectUtil.isEmpty(fieldValue)) {
return;
@ -131,9 +112,9 @@ public class QueryHelper {
* @param queryAnnotation
* 查询注解
* @param fieldName
* 属性
* 字段
* @param fieldValue
* 属性
* 字段
* @param queryWrapper
* MyBatis Plus 查询条件封装对象
* @param <R>

View File

@ -47,6 +47,23 @@ public class CheckUtils extends Validator {
throwIfNull(obj, message, EXCEPTION_TYPE);
}
/**
* 如果为空抛出异常
*
* @param obj
* 被检测的对象
* @param entityName
* 实体名
* @param fieldName
* 字段名
* @param fieldValue
* 字段值
*/
public static void throwIfNull(Object obj, String entityName, String fieldName, Object fieldValue) {
String message = String.format("%s 为 [%s] 的 %s 记录已不存在", fieldName, fieldValue, entityName);
throwIfNull(obj, message, EXCEPTION_TYPE);
}
/**
* 如果不为空抛出异常
*
@ -59,6 +76,23 @@ public class CheckUtils extends Validator {
throwIfNotNull(obj, message, EXCEPTION_TYPE);
}
/**
* 如果不为空抛出异常
*
* @param obj
* 被检测的对象
* @param entityName
* 实体名
* @param fieldName
* 字段名
* @param fieldValue
* 字段值
*/
public static void throwIfNotNull(Object obj, String entityName, String fieldName, Object fieldValue) {
String message = String.format("%s 为 [%s] 的 %s 记录已存在", fieldName, fieldValue, entityName);
throwIfNotNull(obj, message, EXCEPTION_TYPE);
}
/**
* 如果为空抛出异常
*

View File

@ -16,8 +16,6 @@
package top.charles7c.cnadmin.monitor.model.query;
import static top.charles7c.cnadmin.common.annotation.Query.Type;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@ -55,7 +53,7 @@ public class OperationLogQuery implements Serializable {
* 操作内容
*/
@Schema(description = "操作内容")
@Query(type = Type.INNER_LIKE)
@Query(type = Query.Type.INNER_LIKE)
private String description;
/**
@ -69,7 +67,7 @@ public class OperationLogQuery implements Serializable {
* 操作时间
*/
@Schema(description = "操作时间")
@Query(type = Type.BETWEEN)
@Query(type = Query.Type.BETWEEN)
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private List<Date> createTime;
}

View File

@ -16,7 +16,6 @@
package top.charles7c.cnadmin.monitor.service.impl;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -74,8 +73,8 @@ public class LogServiceImpl implements LogService {
QueryWrapper<LogDO> queryWrapper = QueryHelper.build(query);
// 限定查询信息
String[] fieldNameArr = ReflectUtils.getNonStaticFieldsName(OperationLogVO.class);
List<String> columnNameList = Arrays.stream(fieldNameArr).map(StrUtil::toUnderlineCase)
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(OperationLogVO.class);
List<String> columnNameList = fieldNameList.stream().map(StrUtil::toUnderlineCase)
.filter(n -> !n.endsWith("string")).collect(Collectors.toList());
queryWrapper.select(columnNameList);
@ -100,8 +99,8 @@ public class LogServiceImpl implements LogService {
.like(LogDO::getRequestUrl, SysConsts.LOGOUT_URI));
// 限定查询信息
String[] fieldNameArr = ReflectUtils.getNonStaticFieldsName(LoginLogVO.class);
List<String> columnNameList = Arrays.stream(fieldNameArr).map(StrUtil::toUnderlineCase)
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(LoginLogVO.class);
List<String> columnNameList = fieldNameList.stream().map(StrUtil::toUnderlineCase)
.filter(n -> !n.endsWith("string")).collect(Collectors.toList());
queryWrapper.select(columnNameList);
@ -119,8 +118,8 @@ public class LogServiceImpl implements LogService {
QueryWrapper<LogDO> queryWrapper = QueryHelper.build(query);
// 限定查询信息
String[] fieldNameArr = ReflectUtils.getNonStaticFieldsName(SystemLogVO.class);
List<String> columnNameList = Arrays.stream(fieldNameArr).map(StrUtil::toUnderlineCase)
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(SystemLogVO.class);
List<String> columnNameList = fieldNameList.stream().map(StrUtil::toUnderlineCase)
.filter(n -> !n.endsWith("string")).collect(Collectors.toList());
queryWrapper.select(columnNameList);
@ -136,7 +135,7 @@ public class LogServiceImpl implements LogService {
@Override
public SystemLogDetailVO get(Long id) {
LogDO logDO = logMapper.selectById(id);
CheckUtils.throwIfNull(logDO, String.format("ID为 [%s] 的日志已不存在", id));
CheckUtils.throwIfNull(logDO, "LogDO", "ID", id);
SystemLogDetailVO detailVO = BeanUtil.copyProperties(logDO, SystemLogDetailVO.class);
this.fill(detailVO);

View File

@ -112,7 +112,7 @@ mybatis-plus:
# MyBatis 自动映射策略
# NONE不启用 PARTIAL只对非嵌套 resultMap 自动映射 FULL对所有 resultMap 自动映射
auto-mapping-behavior: PARTIAL
# MyBatis 自动映射时未知列或未知属性处理策
# MyBatis 自动映射时未知列或未知属性处理策
# NONE不做处理 WARNING打印相关警告 FAILING抛出异常和详细信息
auto-mapping-unknown-column-behavior: NONE
# 日志配置