1.注解相关功能实现
- 定义属性注解
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.vehicle.manager.core.serializer.DicSerializer;import java.lang.annotation.*;/*** @author zr 2024/2/28*/
@JacksonAnnotationsInside
@JsonSerialize(using = DicSerializer.class
)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Dic {String code();String fieldName()default "";
}
- 定义字典序列化器
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.vehicle.manager.core.annotation.Dic;
import org.springframework.util.StringUtils;import java.io.IOException;
import java.util.Objects;/*** @author zr 2024/2/28*/public class DicSerializer extends JsonSerializer<String> implements ContextualSerializer {private String code;private String fieldName;public DicSerializer(String code, String fieldName) {this.code = code;this.fieldName = fieldName;}public DicSerializer() {}@Overridepublic void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {jsonGenerator.writeString(s);jsonGenerator.writeFieldName(fieldName);//这一步是通过code(字典类型code)和value(字段转换前的值)获取name(字段转换后的值),String name = DicData.getNameByCodeAndValue(this.code,s);jsonGenerator.writeString(name);}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {if(beanProperty !=null){if(Objects.equals (beanProperty.getType ().getRawClass (), String.class)){Dic t =beanProperty.getAnnotation (Dic.class);if(t !=null){String beanFieldName = beanProperty.getName();if(StringUtils.hasText(t.fieldName())){beanFieldName = t.fieldName();}return new DicSerializer(t.code(),beanFieldName+"Text");}}return serializerProvider.findValueSerializer (beanProperty.getType (), beanProperty);}return serializerProvider.findNullValueSerializer (beanProperty);}
}
- 虚假的字典数据类
import java.util.HashMap;
import java.util.Map;/*** 字典数据*/
public class DicData {public static final Map<String, Map<Object,String>> dicData = new HashMap<>();static {// todo 目前写死,可存入数据库或缓存// 车辆状态Map<Object,String> m1 = new HashMap();m1.put("0","初始化");dicData.put("carStatus",m1);}public static String getNameByCodeAndValue(String code,String value){return dicData.get(code).get(value);}}
2.功能测试
测试场景:
- 使用mybatis plus查询数据库car表,将数据封装到CarDO(Car)
- 在service层将CarDO转换为CarVo,同时将CarDO的status字段通过注解转换并生成一个新的字段statusText
- CarDO
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;import java.time.LocalDate;import com.baomidou.mybatisplus.annotation.TableId;import java.time.LocalDateTime;import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.vehicle.manager.core.annotation.Dic;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.io.Serializable;/*** <p>* 车辆信息* </p>** @author MybatisGenerator* @since 2024-02-21*/
@TableName("car")
@ApiModel("车辆实体类")
@Data
//@Accessors(chain = true)
public class Car extends BaseEntity implements Serializable {private static final long serialVersionUID = 2781951723978392659L;/*** 自增id*/@TableId(value = "id", type = IdType.AUTO)private Long id;// *****其他属性省略*****/*** 车辆状态*/@TableField("status")private String status;
}
- CarVo
此处Vo属性上加上自定义注解
@Dic
import com.fasterxml.jackson.annotation.JsonFormat;
import com.vehicle.manager.core.annotation.Dic;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.time.LocalDate;/*** <p>* 车辆信息* </p>** @author MybatisGenerator* @since 2024-02-21*/
@ApiModel("车辆实体类")
@Data
@Accessors(chain = true)
public class CarVo extends BaseVo implements Serializable {private static final long serialVersionUID = 2781951723978392659L;/*** 自增id*/@ApiModelProperty("自增id")private Long id;// *****其他属性省略*****/*** 车辆状态*/@ApiModelProperty("车辆状态")@Dic(code = "carStatus")private String status;}
- 相关service实现类(service接口我就不写了)
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vehicle.manager.core.mapper.CarMapper;
import com.vehicle.manager.core.model.Result;
import com.vehicle.manager.core.model.dto.CarQueryDto;
import com.vehicle.manager.core.model.entity.Car;
import com.vehicle.manager.core.model.enumeration.CommonResultStatus;
import com.vehicle.manager.core.model.vo.CarVo;
import com.vehicle.manager.core.service.CarService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author zr 2024/2/26*/
@Service
public class CarServiceImpl implements CarService {@Autowiredprivate CarMapper carMapper;@Overridepublic Result page(CarQueryDto carQueryDto) {Page<Car> rowPage = new Page(carQueryDto.getPageNum(),carQueryDto.getPageSize());LambdaQueryWrapper<Car> queryWrapper = new LambdaQueryWrapper<>();Page<Car> carPage = carMapper.selectPage(rowPage, queryWrapper);IPage<CarVo> carVoIPage = carPage.convert(res -> getCarVo(res));return Result.success(carVoIPage);}/*** carDo 转 carVo* @param res* @return*/private static CarVo getCarVo(Car res) {CarVo carVo = new CarVo();BeanUtils.copyProperties(res, carVo);return carVo;}/*** 通过id查询数据,并封装到carDo中*/@Overridepublic Result getById(Integer carId) {Car car = carMapper.selectById(carId);CarVo carVo = getCarVo(car);return Result.success(carVo);}}
- 在48行打上断点debug
- 返回给前端的vo数据
可以看到通过注解生成了一个statusText字段,并且为字段中配置的转换后的值