Java:如何巧妙地为 200 个字段创建一个数据映射器实用程序,而不是再次重复相同的检查?

标签 java design-patterns datamapper boilerplate

假设我们有如下场景

if (!areEquals(empFraMD.getUserId(), empFraBubba.getUserId())) {
            empFraMD.setUserId(empFraBubba.getUserId());
            updated = true;
} 

if (!areEquals(empFraMD.getFirstName(), empFraBubba.getFirstName())){
            empFraMD.setFirstName(empFraBubba.getFirstName());
            updated = true;
}
 .........200 Times check for 200 different parameter. 150 Times String checks 20 times integer checks. 
 //EmpFraMD is current employees in Database and empFraBubba is employees fetched from SFTP 
    and both are objects of same class. The requirement here is just to update database 
    only in case difference

updated 标志只是在代码末尾设置,如果 update 为 true,则在数据库中 setLastUpdated(now) 。

是否有一种巧妙的方法可以使用设计模式或 bean 或其他某种转换方式在 Java 中执行此操作,而不是一次又一次地编写相同的 block ?

最佳答案

嗯,这很简单 - 编写一个比较器来检查功能,如果不满足则执行逻辑 作为一个选项,您可以创建自己的注释来检查更改事实,因此如果发生更改,您将执行您的逻辑

 public T updateEntity(T entity) {
    try {
      Field[] declaredFields = this.getClass().getDeclaredFields();
      for (Field field : declaredFields) {
        if (!field.isAnnotationPresent(IgnoreUpdating.class)) {
          Method readMethod = new PropertyDescriptor(field.getName(), this.getClass())
              .getReadMethod();
          if (field.getType().isAssignableFrom(String.class)) {
            updateColumn(entity, field.getName(), readMethod.invoke(this, (Object[]) null),
                Types.DATA_TYPE_STRING);
********************************************                
          } else if (field.getType().isAssignableFrom(BigDecimal.class)) {
            updateColumn(entity, field.getName(), readMethod.invoke(this, (Object[]) null),
                Types.DATA_TYPE_BIGDECIMAL);
          }
        }
      }
      return entity;
    } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException
        | InvocationTargetException e) {
      log.error("updateEntity: "+e.getMessage(), e);
      throw new Exception(e.getMessage(),e);
    }   
  }

public static <T> T updateColumn(T entity, String columnName, Object value, String type) throws Exception {
    try {
      Method writeMethod = new PropertyDescriptor(columnName, entity.getClass()).getWriteMethod();
      if (value != null) {
        boolean isnull = false;
        ***********************
        if (isnull) {
          writeMethod.invoke(entity, (Object) null);
        } else {
          writeMethod.invoke(entity, value);
        }
      }
      return entity;
    } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException
        | InvocationTargetException e) {
      log.error("updateColumn: "+e.getMessage(), e);
      throw new Exception(e.getMessage(),e);
    }
  } 

还有一个调用:

User user = model.updateEntity(userForUpdate);

创建一个这样的类

public class UpdatableModel<T> {
  public T updateEntity(T entity);
  public static <T> T updateColumn(T entity, String columnName, Object value, String type) throws Exception;
}

像我下面展示的那样实现它们

顺便说一句: 也许您已经拿起hibernate introcepters

关于Java:如何巧妙地为 200 个字段创建一个数据映射器实用程序,而不是再次重复相同的检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57589045/

相关文章:

java - 如何在没有 printStackTrace 的情况下从异常中获取 stackTrace?

java - 如何获得具有线性分布的随机日期?

java - 对 Stream 的终端调用永远不会执行

java - SpringMvc java.lang.NullPointerException - 配置是否正确

java - 需要帮助识别此代码中使用的 'override method' 模式

ruby - 使用 Datamapper 遍历整个表的最有效方法是什么?

design-patterns - 你能说出多少个非 GOF 模式?

java - 设计模式如何在使用 List 时避免 instanceOf

ruby-on-rails - Datamapper:通过关联对结果进行排序

java - jackson :如何仅序列化带注释的属性