#java #spring #spring-boot #mapping #dto
#java #spring #весенняя загрузка #сопоставление #dto
Вопрос:
Я с помощью RestController обновляю данные в db, но у меня проблема. Когда я обновляю значение, если значение из моего обновления равно нулю, оно всегда обновляет данные до значения db null. Я этого не хочу. Я хочу, чтобы, если в моем запросе 1 поле со значением null, я не хотел его обновлять.
Ниже приведен мой код :
Контроллер:
RestController
@RequestMapping("/api/products")
@Api(value = "ProductControllerApi",produces = MediaType.APPLICATION_JSON_VALUE)
public class ProductController {
@Autowired
private ProductService productService;
@PatchMapping("/{id}")
public ResponseEntity<ProductResDto> updateProduct(@RequestBody ProductReqDto productReqDto, @PathVariable String id) {
return ResponseEntity.ok(productService.updateProduct(product,id));
}
ProductReqDto:
public class ProductReqDto {
private String name;
private String type;
private String category;
private String description;
private Double prince;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrince() {
return prince;
}
public void setPrince(Double prince) {
this.prince = prince;
}
}
ProductResDto:
public class ProductResDto {
private String name;
private String type;
private String category;
private Double prince;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrince() {
return prince;
}
public void setPrince(Double prince) {
this.prince = prince;
}
}
Отображение dto:
private ProductDto convertToProductDto(ProductReq product) {
return modelMapper.map(product, ProductResDto.class);
}
Как мне обработать метод converttoproductdтолько для сопоставления со значением, отличным от null. Потому что, если сопоставить одно поле : пример : product_name = null , оно вставляется в db null. Я хочу, чтобы поле ProductReq имело значение, отображало его и сохраняло другое другое поле в базе данных (не присваивать ему значение null, если оно не содержит значения из ProductReq).
Пример:
**ReqProductDto.class**
private String name;
private String type;
private String category;
private String description;
private Double prince;
но если пользователь обновляет только два поля:
private String name;
private String type;
Я хочу весной обновить имя поля и тип поля пользовательского ввода и сохранить категорию, описание, принца в моей базе данных. В моем случае, если пользователь обновляет два поля: имя и тип поля, spring обновит его, но spring установит, что категория, описание, принц имеют значение null в моей базе данных. Я этого не хочу.
Пожалуйста, помогите мне, спасибо.
Комментарии:
1. итак, если какое-либо поле
null
вы не хотите обновлять? или обновить поля, в которых есть значения, и не обновлятьnull
поле, которое вы ищете?2. У меня есть вопрос об обновлении. Пожалуйста, помогите
3. как вы сохраняете эти данные в базе данных? используете ли вы hibernate с spring-jpa?
4. Нет. Я использую TypeQuery и метод обновления записи, который выглядит следующим образом: objectdb.com/java/jpa/query/api .
Ответ №1:
Вы пометили это как spring-boot, поэтому я предполагаю, что вы, возможно, используете контроллеры и проверяете их параметры. Если это так, просто сделайте
import javax.validation.constraints.NotNull;
public class ProductReqDto {
@NotNull
private String name;
@NotNull
private String type;
@NotNull
private String category;
@NotNull
private String description;
@NotNull
private Double prince;
...
}
и используйте @Valid для ваших контроллеров следующим образом
@PatchMapping("/{id}")
public ResponseEntity<ProductResDto> updateProduct(@RequestBody @Valid ProductReqDto productReqDto, @PathVariable String id) {
return ResponseEntity.ok(productService.updateProduct(product,id));
}
Тогда ваш объект будет проверен при создании экземпляра.
Комментарии:
1. Я знаю это, но я хочу, чтобы, если для одного поля не требуется значение null, но пользователь забыл его установить, оно не отображалось в базе данных. Пользователь поля Value не установил сохранение значения в базе данных. Не установлено значение null
Ответ №2:
То, что вы хотите, в основном используется для сопоставления ИСПРАВЛЕНИЙ. При сопоставлении PUT все поля объекта необходимо переопределить, но при сопоставлении PATCH необходимо переопределить только те поля, которые предоставлены, остальные изменять не нужно.
Итак, для существующей записи,
employee{ employeeId = "A2RTD", empName = "satish", "country": "India"}
И теперь одно необязательное поле MobileNo необходимо обновить вместе со страной
Запрос DTO будет содержать все поля, отличные от id, но только номер страны и мобильного телефона не будет равен null
В этом сценарии мы можем использовать BeanUtils, который является частью пакета spring
import org.springframework.beans.BeanUtils;
public static Object getDtoMapping(Object source, Object destination) {
BeanUtils.copyProperties(source, destination, getNullFieldNames(source));
return destination;
}
public static String[] getNullFieldNames(Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> fieldNames = new HashSet<>();
for (PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null)
fieldNames.add(pd.getName());
}
String[] result = new String[fieldNames.size()];
return fieldNames.toArray(result);
}
Функция «getNullFieldNames» вернет имена полей, которые имеют значение null. Таким образом, эти поля не будут сопоставлены, согласно третьему необязательному параметру в BeanUtils
И вам нужно передать
// PATCH
EmployeeDao emp = findById(empCode);
emp = (EmployeeDao) getDtoMapping(empUpdateDto, emp);
Здесь, в BeanUtil copyProperties, третий параметр необязателен. Если вы даете, это работает для сопоставления ИСПРАВЛЕНИЙ, если вы не даете, это ведет себя как сопоставление PUT.
Поскольку для сопоставления PUT игнорирование null равносильно не игнорированию. Вы можете использовать то же самое в POST, также помещая сопоставление.
// POST MAPPING
EmployeeDao emp = (EmployeeDao) getDtoMapping(empCreateDto, new Employee());