| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package com.malk.base;
- import cn.hutool.core.util.ObjectUtil;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.serializer.SerializerFeature;
- import com.fasterxml.jackson.annotation.JsonInclude;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import lombok.SneakyThrows;
- import org.apache.commons.lang3.StringUtils;
- import org.springframework.beans.BeanUtils;
- import org.springframework.beans.BeanWrapper;
- import org.springframework.beans.BeanWrapperImpl;
- import java.beans.PropertyDescriptor;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- /**
- * 基础对象
- *
- * @JsonInclude(JsonInclude.Include.NON_NULL):类注解过滤null字段,包含入参和返回值【参数类搭配 @Data,才可以实例化返回值以及ToString输出】
- * -
- * lombok
- * @Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
- * @AllArgsConstructor : 注在类上,提供类的全参构造
- * @NoArgsConstructor : 注在类上,提供类的无参构造
- * @Setter : 注在属性上,提供 set 方法
- * @Getter : 注在属性上,提供 getDefault 方法
- * @EqualsAndHashCode : 注在类上,提供对应的 equals 和 hashCode 方法
- * @Log4j/@Slf4j : 注在类上,提供对应的 Logger 对象,变量名为 log
- * @Builder:为类生成相对略微复杂的构建器API。来初始化实例对象::类名.属性(值).属性(值).build()
- * @Singular:在使用@Singular注释注释一个集合字段(使用@Builder注释类),lombok会将该构建器节点视为一个集合,并生成两个adder方法而不是setter方法::点一次集合增加一个元素
- * @Builder.Default:在类中id和insertTime上都添加注解@Builder.Default,当在使用这个实体对象时,就不需要在为这两个字段进行初始化值
- */
- @Data
- @NoArgsConstructor
- @JsonInclude(JsonInclude.Include.NON_NULL)
- public abstract class BaseDto {
- /**
- * 对象拷贝: 若是复制一个对象, 建议使用 cloneParam 避免性能问题
- */
- @Deprecated
- @SneakyThrows
- public BaseDto copyParam() {
- BaseDto dto = this.getClass().newInstance();
- BeanUtils.copyProperties(this, dto);
- return dto;
- }
- /**
- * * todo: 4.11 继承Serializable后执行深拷贝, 不能类型转换, 不继承Serializable则返回
- * 对象拷贝: 复制一个新的对象, 避免条件被修改, 尤其并发下分页混乱情况
- */
- public BaseDto cloneParam() {
- return ObjectUtil.clone(this);
- }
- /**
- * 对象属性合并: jda之save接口会以传入数据为准,若传入为空或不传入,更新会置空。目前解决办法两种,通过注解实现JPQL/SQL,或者查询出数据,将未传入字段属性拷贝后再更新【性能消耗】
- */
- public void mergeParam(BaseDto modifyDo) {
- BeanUtils.copyProperties(this, modifyDo, getNotNullPropertyNames(modifyDo));
- }
- // 忽略有值的字段
- private static String[] getNotNullPropertyNames(Object target) {
- final BeanWrapper src = new BeanWrapperImpl(target);
- PropertyDescriptor[] pds = src.getPropertyDescriptors();
- Set<String> emptyNames = new HashSet();
- for (PropertyDescriptor pd : pds) {
- Object srcValue = src.getPropertyValue(pd.getName());
- if (srcValue != null) {
- // 此处判断可根据需求修改, 目前过滤不为null
- emptyNames.add(pd.getName());
- }
- }
- String[] result = new String[emptyNames.size()];
- return emptyNames.toArray(result);
- }
- /**
- * 传入映射的Map, 将实体属性和Map的key转换, 返回Map
- */
- public Map convertEntity(Map<String, String> reflect) {
- Map map = JSON.parseObject(JSON.toJSONString(this, SerializerFeature.WriteNullStringAsEmpty), Map.class);
- Map<String, String> formData = new HashMap();
- for (String key : reflect.keySet()) {
- String content = String.valueOf(map.get(key));
- // json序列化已经将空字符串过滤, 若转换还有null字符串, 可能是key为null或SerializerFeature未指定到类型, 如Date
- if (StringUtils.isNotBlank(content) && !content.equals("null")) formData.put(reflect.get(key), content);
- }
- return formData;
- }
- /**
- * Map时间格式化, 直接从数据库取值后Map会有市区差, 方法1见BasePo, @Temporal & @JsonFormat 注解
- * -
- * [单独时间格式化 [废弃]]
- * * JSON.parseArray(JSON.toJSONString(data), Map.class).stream().map(item -> {
- * * item.put("tStoreInTime", UtilDateTime.formatDateTime(new Date(UtilMap.getLong(item, "tStoreInTime"))));
- * * return item;
- * * });
- */
- public static final Object jsonFormatDateTime(Object data) {
- return JSON.parse(JSON.toJSONString(data, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat));
- }
- }
|