【问题标题】:Spring CrudRepository: why to invent a new generic type SSpring CrudRepository:为什么要发明一个新的泛型类型 S
【发布时间】:2014-10-14 02:32:00
【问题描述】:

您能否给我一个提示为什么在 CrudRepository 接口中的“save”方法中发明了一个新的泛型类型“S”。 (见org.springframework.data.repository.CrudRepository

这是 CrudRepository 类的提取:

public interface CrudRepository<T, ID extends Serializable>
         extends Repository<T, ID> {
    /**
     * Saves a given entity. Use the returned instance for further
     * operations as the save operation might have changed the
     * entity instance completely.
     * 
     * @param entity
     * @return the saved entity
     */
     <S extends T> S save(S entity);

     ...

     /**
      * Deletes a given entity.
      * 
      * @param entity
      * @throws IllegalArgumentException in case the given entity is (@literal null}.
      */
      void delete(T entity);
}

请注意,在第二种方法“删除”中,同一实体的类型为 T。 方法“save”表示它返回一个“S”类型的对象。所以这是不可能实现方法“保存”这样说的:

@Override
public <S extends MyType> S save(S entity) {
    save(entity);
    return findOne(entity.getMyTypeId()); // Type mismatch: cannot convert from MyType to S
}

另一个问题是如何更好地实现“保存”方法?

【问题讨论】:

    标签: java spring generics


    【解决方案1】:

    目的是,一般来说,Spring *Repository 接口是由 Spring Data 自动实现的,而不是手动实现的,并且很方便知道您将从 save 操作中返回相同类型的对象您输入。特别是对于面向文档的数据存储,看到子类与超类持久保存在同一个存储库中并不罕见,并且使用S extends T 作为参数和返回类型确保您可以继续使用相同的持久对象保存前会有的界面。

    【讨论】:

    • chrylis,谢谢!如果我喜欢这个接口 CrudRepository 并将它用作我的 *RepositoryImpl 的合同怎么办。如何更好地实现“保存”方法?
    【解决方案2】:

    似乎保存的实现之一可以是:

    @Override
    public <S extends MyType> Iterable<S> save(Iterable<S> entities) {
        List<S> result = new ArrayList<S>();
        for (S entity : entities) {
            result.add(save(entity));
        }
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      相关资源
      最近更新 更多