Java 当仅修改实体obj的几个字段且剩余字段不应为空时,如何更新Hibernate实体记录
对于此代码是否有其他不同的解决方案。 对于每个pojo类,我们必须检查来自浏览器的修改数据,并且我们将只将修改后的数据存储到数据库中 如下所示,billingTax obj来自更新数据的浏览器 从数据库中检索billingtaxDbObject obj,我们将检查更新后的数据是否发生更改 如果pojo类有20个字段,我们必须编写20个if条件 如果pojo类有5个字段,我们必须编写5个if条件 如果检查wheter数据的条件被修改,或者没有其他最简单的方法,那么就不写了Java 当仅修改实体obj的几个字段且剩余字段不应为空时,如何更新Hibernate实体记录,java,hibernate,Java,Hibernate,对于此代码是否有其他不同的解决方案。 对于每个pojo类,我们必须检查来自浏览器的修改数据,并且我们将只将修改后的数据存储到数据库中 如下所示,billingTax obj来自更新数据的浏览器 从数据库中检索billingtaxDbObject obj,我们将检查更新后的数据是否发生更改 如果pojo类有20个字段,我们必须编写20个if条件 如果pojo类有5个字段,我们必须编写5个if条件 如果检查wheter数据的条件被修改,或者没有其他最简单的方法,那么就不写了 @Override
@Override
public BillingTax update(BillingTax billingTax) throws DataInsufficientException, RecordNotFoundException {
log.debug("BillingTaxServiceImpl.update()....................");
try {
if (billingTax == null)
throw new DataInsufficientException("billingTax object is null");
BillingTax billingtaxDbObject = get(billingTax.getId());
if (billingtaxDbObject == null)
throw new RecordNotFoundException("billingTax object is not found in database");
if (billingTax.getTaxApplyType() != null
&& !billingTax.getTaxApplyType().equals(billingtaxDbObject.getTaxApplyType()))
billingtaxDbObject.setTaxApplyType(billingTax.getTaxApplyType());
if (billingTax.getCode() != null && !billingTax.getCode().trim().equalsIgnoreCase("null")
&& !billingTax.getCode().equalsIgnoreCase(billingtaxDbObject.getCode()))
billingtaxDbObject.setCode(billingTax.getCode());
if (billingTax.getName() != null && !billingTax.getName().trim().equalsIgnoreCase("null")
&& !billingTax.getName().equalsIgnoreCase(billingtaxDbObject.getName()))
billingtaxDbObject.setName(billingTax.getName());
if (billingTax.getDescription() != null && !billingTax.getDescription().trim().equalsIgnoreCase("null")
&& !billingTax.getDescription().equalsIgnoreCase(billingtaxDbObject.getDescription()))
billingtaxDbObject.setDescription(billingTax.getDescription());
if (billingTax.getServiceTypeForTax() != null
&& !billingTax.getServiceTypeForTax().equals(billingtaxDbObject.getServiceTypeForTax()))
billingtaxDbObject.setServiceTypeForTax(billingTax.getServiceTypeForTax());
if (billingTax.getTaxValue() != null && !billingTax.getTaxValue().equals("null")
&& !billingTax.getTaxValue().equals(billingtaxDbObject.getTaxValue()))
billingtaxDbObject.setTaxValue(billingTax.getTaxValue());
if (billingTax.getStatus() != null && !billingTax.getStatus().equals(billingtaxDbObject.getStatus()))
billingtaxDbObject.setStatus(billingTax.getStatus());
if (billingTax.getOrderNo() != null && !billingTax.getOrderNo().equals("null")
&& !billingTax.getOrderNo().equals(billingtaxDbObject.getOrderNo()))
billingtaxDbObject.setOrderNo(billingTax.getOrderNo());
if (billingTax.getId() != null && !billingTax.getId().trim().equalsIgnoreCase(billingtaxDbObject.getId())
&& !billingTax.getId().equalsIgnoreCase(billingtaxDbObject.getId()))
billingtaxDbObject.setId(billingTax.getId());
if (billingTax.getStartDate()!= null && !billingTax.getStartDate().equals(billingtaxDbObject.getStartDate()))
billingtaxDbObject.setStartDate(billingTax.getStartDate());
if (billingTax.getEndDate()!= null && !billingTax.getEndDate().equals(billingtaxDbObject.getEndDate()))
billingtaxDbObject.setEndDate(billingTax.getEndDate());
billingtaxDbObject.setUpdatedDate(new Date());
return billingTaxDAO.update(billingtaxDbObject);
} catch (Exception e) {
log.error("BillingTaxServiceImpl.update()....................exception:" + e.getMessage());
throw e;
}
}
若可以避免检查dto和实体之间的更改,并更新来自web的所有字段,那个么可以使用hibernate的动态更新来完成此操作。若您需要从web和实体中检查dto,那个么可以使用ApacheBean util来查找所有更改的值(或者使用spring util,若您有或从java反射…),并使用动态更新来更新它 见: copyProperties()//有3个方法 检查它在源代码中的工作方式。 创建您自己的util方法,类似于BeanUtils.copyProperties(),但使用您需要的逻辑(不为null,也不等于源实体值) 还可以使用BeanUtils提供的方法获取PropertyDescriptor: 公共静态PropertyDescriptor[]getPropertyDescriptors(类clazz) 抛出BeansException 迭代PropertyDescriptor的数组,并检查您是否需要(使用将值设置到源代码中) 使用这种方法,您只需将不为null且已更改(如果需要)的属性填充到billingtaxDbObject中并进行更新
您可以将copy/merge方法放入某个util类中,并在需要通过一些检查将dto复制到实体的所有地方重用它。这是通过从pojo类获取所有字段/属性并使用wheter null数据或修改的数据来实现的。 代码如下: copyProperties(billingTax、billingtaxDbObject) 公共void copyProperties(BillingTax源、BillingTax目标)引发异常{
if (source == null)
throw new DataInsufficientException("billingTax object is null");
if (dest == null)
throw new RecordNotFoundException("billingtaxDbObject object is not found in database");
try{
for (Field field : source.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object sourceValue = field.get(source);
Object destValue=field.get(dest);
if(sourceValue!=null && sourceValue!="" && sourceValue!="null"){
if(sourceValue instanceof String){
if(!sourceValue.toString().trim().equalsIgnoreCase("null")){
if(!sourceValue.toString().equalsIgnoreCase(destValue.toString())){
field.set(dest, sourceValue);
System.err.println(field.getName()+" is modified:"+field.get(dest));
}
}
}
else{
if(!sourceValue.equals("null") && !sourceValue.equals(destValue)){
field.set(dest, sourceValue);
System.err.println(field.getName()+" is modified:"+field.get(dest));
}
}
}
}
System.out.println();
}catch (Exception e) {
throw e;
}
}
公共类CopyConverter{
private List errorMessages=新建ArrayList();
private int countSuccess=0;
公共CopyConverter转换(T源、T目标、设置信号域){
copyProperties(源、目标、ignoreFields);
归还这个;
}
公共布尔hasError(){
返回errorMessages.isEmpty();
}
公共列表getErrorMessages(){
返回错误消息;
}
私有布尔copyProperties(T源、T目标、设置ignoreFields){
Objects.requirennull(源“…错误消息…”);
requirennull(目标,“…错误消息…”);
试一试{
Map fieldNameMapping=buildFiledMap(target.getClass()。
getDeclaredFields());
ignoreFields=(ignoreFields==null?新HashSet():ignoreFields);
对于(Map.Entry fieldEntry:fieldNameMapping.entrySet()){
if(ignoreFields.contains(fieldEntry.getKey())){
继续;
}
Field=fieldEntry.getValue();
字段。setAccessible(true);
Object sourceValue=field.get(source);
对象targetValue=field.get(源);
if(isChangedAsString(sourceValue,targetValue)){
设置字段(目标、源值);
继续;
}
if(isChangedAsObject(sourceValue,targetValue)){
设置字段(目标、源值);
}
countSuccess++;
}
}捕获(例外e){
errorMessages。添加(“…”);
日志信息(…);
}
return countSuccess==0;
}
私有映射buildFiledMap(字段[]字段){
Map fieldMap=新的HashMap(fields.length);
//Stream.of(fields.collect(Collectors.toMap())
用于(字段:字段){
fieldMap.put(field.getName(),field);
}
返回场地图;
}
私有布尔值isChangedAsObject(对象obj1、对象obj2){
返回(obj1==null&&obj2!=null)| |(obj1!=null&&obj1.equals(obj1));
}
私有布尔值isChangedAsString(对象obj1、对象obj2){
if(obj1字符串实例和obj2字符串实例){
字符串值1=(字符串)obj1;
字符串值2=(字符串)obj2;
返回值1!=null&&
!value1.trim()
!value1.相等信号情况(value2);
}
返回false;
}
}
为什么在调用set之前需要检查它们是否不同?为了避免在数据库中存储null值。您已经在检查null值。为什么需要检查它们是否不同?我们正在使用SpringBoot。但我对spring是新手。我想知道如何使用spring util。请您使用BeanUtils,a,用一个例子解释一下我无法理解源代码。所以我创建了自己的逻辑,它将检查非空字段,并将数据从源代码修改为dest obj。请您用一个包含两个字段的pojo类进行解释。
public class CopyConverter<T> {
private List<String> errorMessages = new ArrayList<>();
private int countSuccess = 0;
public CopyConverter<T> convert(T source, T target, Set<String> ignoreFields){
copyProperties(source,target,ignoreFields);
return this;
}
public boolean hasError(){
return errorMessages.isEmpty();
}
public List<String> getErrorMessages(){
return errorMessages;
}
private boolean copyProperties(T source ,T target , Set<String> ignoreFields) {
Objects.requireNonNull(source , "..error message...");
Objects.requireNonNull(target , "..error message...");
try {
Map<String, Field> fieldNameMapping = buildFiledMap(target.getClass().
getDeclaredFields());
ignoreFields = (ignoreFields == null ? new HashSet<>() : ignoreFields);
for (Map.Entry<String, Field> fieldEntry : fieldNameMapping.entrySet()) {
if (ignoreFields.contains(fieldEntry.getKey())) {
continue;
}
Field field = fieldEntry.getValue();
field.setAccessible(true);
Object sourceValue = field.get(source);
Object targetValue = field.get(source);
if (isChangedAsString(sourceValue, targetValue)) {
field.set(target, sourceValue);
continue;
}
if (isChangedAsObject(sourceValue, targetValue)) {
field.set(target, sourceValue);
}
countSuccess++;
}
} catch (Exception e) {
errorMessages.add(".......");
log.info(....);
}
return countSuccess == 0;
}
private Map<String, Field> buildFiledMap(Field[] fields) {
Map<String, Field> fieldMap = new HashMap<>(fields.length);
//Stream.of(fields).collect(Collectors.toMap())
for (Field field : fields) {
fieldMap.put(field.getName(), field);
}
return fieldMap;
}
private boolean isChangedAsObject(Object obj1, Object obj2) {
return (obj1 == null && obj2 != null) || (obj1 != null && !obj1.equals(obj1));
}
private boolean isChangedAsString(Object obj1, Object obj2) {
if (obj1 instanceof String && obj2 instanceof String) {
String value1 = (String) obj1;
String value2 = (String) obj2;
return value1 != null &&
!value1.trim().equalsIgnoreCase("null") &&//strange check
!value1.equalsIgnoreCase(value2);
}
return false;
}
}