创建具有映射层的DAO

时间:2019-05-21 21:36:10

标签: java oop design-patterns dao

我正在尝试找出布局此设计的最佳方法,并且遇到了一些问题。

我有一个Dao接口,其中R是返回类型,U是数据库记录impl:

public interface Dao<U extends UpdatableRecordImpl> {

  public List<U> insert(List<U> dbRecords);
  public List<U> fetchAll(Select<U> selectQuery);
}

我有一个默认的Dao,它通过以下方式实现Dao:

public class BasicDao<U extends UpdatableRecordImpl> implements Dao<U>{

  protected final DSLContext _dslContext;

  public BasicDao(Configuration configuration, T table) {
    _dslContext = DSL.using(configuration);
    _table = table;
  }

  /**
   * Fetch multiple records from database
   *
   * @param selectQuery input query
   * @return list of records representing the database records
   */
  public List<U> fetchAll(Select<U> selectQuery) {
    return selectQuery.fetchStream().collect(Collectors.toList());
  }

  /**
   * Persists db records
   * <p>
   * Performs a batch operation for more than one record
   *
   * @param dbRecords list of records that need to be persisted
   * @return list of records with updated with id's which were generated by database
   */
  public List<U> insert(List<U> dbRecords) {

    if (dbRecords.isEmpty()) {
      return ImmutableList.of();
    }
    // prepare insert statement
    Result<U> inserted = //insert records
    return inserted;
  }
}

现在我想做的是在此之上有一个映射层。这样我们就可以拥有一个如下所示的类:

  @Override
  public List<M> insert(List<M> mappedRecords) {

    // Map record templates to db records
    List<U> dbRecords = mapList(mappedRecords, this::map);

    //Map the result of inserting to DefaultDao
    return mapList(_defaultDao.insert(dbRecords), this::map);
  }

  @Override
  public List<M> fetchAll(Select<U> select) {
    return StreamEx.of(_defaultDao.fetchAll(select)).map(this::map).toList();
  }

  /**
   * Map list of POJOs' of one type to the list of POJOs' of another type
   *
   * @param records list of POJOs' that need to be mapped
   * @param mapper function to map a single POJO of one type to other POJO type
   * @param <P> Input POJO type
   * @param <B> Output POJO type
   * @return
   */
  protected <P, B> List<B> mapList(List<P> records, Function<P, B> mapper) {
    return StreamEx.of(records).map(mapper).toList();
  }

  /**
   * Transforms a representative record to it's database representation
   * @param mappedRecord mapped representation of database record
   * @return database record
   */
  protected U map(M mappedRecord) {
    return _mapper.map(mappedRecord);
  }

  /**
   * Maps database record to it's mapped representation
   * @param dbRecord database record
   * @return representation of the database record in M type
   */
  M map(U dbRecord) {
    return _mapper.inverse().map(dbRecord);
  }

我曾尝试在BasicDao周围添加一个Decorator层,但是遇到了一个相同的闭包(List<U> insert(List<U> dbRecords)List<M> insert(List<M> dbRecords)具有相同的闭包)的问题。

使用此设置的建议方法是什么?我发现通过让Dao接受两个类(return和recordImpl)发现了一些hacky方式,但这在基本impl(implements Dao<U, U>)中看起来很hacky,并且破坏了执行通用类边界的类中的某些现有功能({{1 }}。

感谢您的帮助。

0 个答案:

没有答案