java 只更新实体的几个字段,而不使用多个if

ncgqoxb0  于 2023-05-05  发布在  Java
关注(0)|答案(2)|浏览(179)

我正在建立一个电子商店作为一个exercise实践新的东西,我现在在这一点上,我应该作出的服务,以编辑的产品,但我认为它可以以某种方式优化
我希望能够更改未定义数量的属性。
例如:我可能想更改产品的名称,然后我可能想更改另一个产品的价格和可用性状态
我设法对Product类的每个属性使用多个if语句来实现这一点
public ResponseEntity〈?〉editProduct(ProductsDto productDto){

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
    try {
        Optional<Products> oldProduct = productsRepository.findById(productDto.getId());

        if (oldProduct.isEmpty()){
            return ResponseEntity.badRequest().body("Product with id: "+productDto.getId()+" not found.");
        }
        
        if (!oldProduct.get().getName().equals(productDto.getName())){
            oldProduct.get().setName(productDto.getName());
        }
        if (!oldProduct.get().getPrice().equals(productDto.getPrice())){
            oldProduct.get().setPrice(productDto.getPrice());
        }
        if (!oldProduct.get().getQuantity().equals(productDto.getQuantity())){
            oldProduct.get().setQuantity(productDto.getQuantity());
        }

    /* n if statements for each attribute in the object */

        productsRepository.save(oldProduct.get());
    }catch(Exception e){
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
    }

    return ResponseEntity.ok().body("New Product added correctly");
}

有一种方法可以使它更有效,也许在某种程度上,如果我在对象中添加一个属性,我不需要添加另一个,如果?
谢谢
Java版本17

----编辑----

ProductDto类与Products类不同,它们具有不同的属性,例如Products引用创建它的用户
在productDto是Product类的反射的情况下,我可以像这样更新产品:productsRepository.save(productDto);
但是,如果dto只对少数字段进行了定价,我该怎么办?我不能保存它,否则我会丢失一些数据
例如:

{
    "id":  "6",
    "name" : "Brioche",
    "price" : "",
    "quantity" : 10,
    "availableFrom" : "",
    "availableUntil" : "13/06/2023 10:00:00"
}

在这种情况下,我只是改变名称,数量和availableUntil

cig3rfwq

cig3rfwq1#

是否要复制所有字段?还是只是其中的一部分你的dto是一个不同的类(ProductDto)还是Product的一个示例?一个选择是使用类似这样的东西:

Product update = mapToProduct(dto);
Product product = oldProduct.get(); 
product.update(update);

然后,在Product类中添加update方法:

class Product {
    String name;
    String price;
    String quantity;

    public void update(Product other) {
        name = other.name;
        price = other.price;
        quantity = other.quantity;
    }
}

或者,你也可以像这样使用BeanUtils:

public void update(Product other) {
    BeanUtils.copyProperties(other, this);
}

它甚至允许您忽略一些字段,例如“id”:

BeanUtils.copyProperties(other, this, "id");

PS:我不是BeanUtils的忠实粉丝,我建议你不要在不同类的对象上使用它。

pjngdqdw

pjngdqdw2#

如果您愿意使用MapStruct,则可以使用此方法
这将相当于您的“Products”类

import com.google.api.client.util.DateTime;
import lombok.AllArgsConstructor;
import lombok.Data;

@AllArgsConstructor
@Data
public class Entity {
  private int id;
  
  private String name;
  
  private double price;
  
  private int quantity;
  
  private DateTime availableFrom;
  
  private DateTime availableUntil;

  private List<String> references;
  
  private boolean moreVariables;
}

这相当于您给我们的DTO示例

import com.google.api.client.util.DateTime;
import lombok.AllArgsConstructor;
import lombok.Data;

@AllArgsConstructor
@Data
public class EntityDto {
  private Integer id;
  
  private String name;
  
  private Double price;
  
  private Integer quantity;
  
  private DateTime availableFrom;
  
  private DateTime availableUntil;
}

这是只将给定参数(不为空)覆盖到旧产品实体的方法

import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.factory.Mappers;

@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface MapperExample {

  void updateEntity(@MappingTarget Entity entity, final EntityDto dto);
  
}

然后当你编译项目的时候就像这样简单的调用Map器

public class YourClass {
  @Autowired
  private MapperExample mapper;

  ...

  public ResponseEntity<?> editProduct(EntityDto dto) { 
    Optional<Entity> entity = productsRepository.findById(dto.getId());
    mapper.updateEntity(entity.get(), dto);
    productsRepository.save(entity.get());

  ...

  }
}

PD:@AllArgsConstructor和@Data是Lombok annotations,有助于避免编写额外的代码,如构造函数或所有getter和setter。
如果您需要有关@Mapper或@MappingTarget注解的更多信息,这里有一些指向MapStruct文档的链接

相关问题