MapStruct生成代码无Setter问题及@Json注解DTO优势咨询
问题解答
一、DTO标注@Json注解的优势
这里的@Json注解泛指Jackson系列的JSON序列化/反序列化注解(如@JsonProperty、@JsonIgnore、@JsonFormat等),核心优势包括:
- 精准控制字段映射:可自定义Java字段与JSON字段的对应关系,比如把Java的
priceId映射为JSON的price_id,解决命名风格差异问题;还能通过@JsonIgnore直接忽略敏感字段(如密码)或无需对外暴露的内部字段。 - 提升序列化性能:明确指定需要处理的字段,避免框架反射遍历类的所有字段,减少不必要的性能开销。
- 增强接口兼容性:当DTO类字段名变更时,通过注解固定JSON字段名,不会影响依赖该接口的前端或其他服务,避免因字段名修改导致的兼容性故障。
- 支持复杂业务场景:比如用
@JsonFormat统一日期格式、用@JsonInclude控制null值是否返回、用@JsonDeserialize自定义特殊类型的反序列化逻辑,满足多样化的业务需求。
二、MapStruct生成Builder模式转换代码的原因
你看到的Builder模式代码是MapStruct的正常行为,原因如下:
- 目标类支持Builder:你的
Price类应该是通过Lombok的@Builder注解、手动实现Builder或者其他方式提供了Builder构建器(比如代码里的Price.PriceBuilder),MapStruct会自动检测到这种构建方式,并优先使用Builder生成转换代码。 - Builder模式本身的优势:
- 保证对象不可变性:构建完成后的
Price对象无法被修改,避免后续代码意外篡改字段值,更符合现代Java的不可变对象设计理念。 - 代码更简洁易读:Builder的链式调用写法(
price.priceId(...).productId(...))比多次调用Setter(price.setPriceId(...); price.setProductId(...);)更紧凑,可读性更高。 - 避免半初始化对象:必须调用
build()才能生成实例,不会出现只设置部分字段的不完整对象,保证数据完整性。
- 保证对象不可变性:构建完成后的
- 可配置切换为Setter:如果你确实想让MapStruct生成Setter风格的代码,可以在MapStruct的
@Mapper注解中添加配置:@Mapper(builder = @Builder(disableBuilder = true)),或者移除Price类的Builder实现,MapStruct就会自动切换为使用Setter方法。
附你提供的MapStruct生成代码:
@Override public Price dtoToModel(PriceDTO pricesDTO) { if ( pricesDTO == null ) { return null; } Price.PriceBuilder price = Price.builder(); price.priceId( pricesDTO.getPrice_Id() ); price.productId( pricesDTO.getProduct_Id() ); price.brandId( pricesDTO.getBrand_Id() ); price.starDate( pricesDTO.getStarDate() ); price.endDate( pricesDTO.getEndDate() ); price.priority( pricesDTO.getPriority() ); price.price( pricesDTO.getPrice_dto() ); if ( pricesDTO.getCurr() != null ) { price.curr( String.valueOf( pricesDTO.getCurr() ) ); } price.price_List( priceDTOSetToPriceSet( pricesDTO.getPriceList_dto() ) ); price.produc( pricesDTO.getProduc() ); return price.build(); }
内容的提问来源于stack exchange,提问作者anodino
相关产品推荐
相关产品推荐

