在 Spring 存储库中<S 扩展 T> 保存(S 实体)是什么意思?



在Spring Data项目中,CrudRepository为正在管理的实体类提供了复杂的CRUD功能。

public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
    <S extends T> S save(S entity);
    T findOne(ID primaryKey);
    Iterable<T> findAll();
    Long count();
    void delete(T entity);
    boolean exists(ID primaryKey);
    // … more functionality omitted.
}

一般来说,我知道"S 扩展 T"是什么意思,即保存操作的返回类型 S必须是 T 的子类型。为什么需要添加诸如约束之类的内容?我认为这样做会很好:

T save (T entity);

如在

void delete(T entity);

我已经用谷歌搜索以寻求更多帮助,并且我已经找到了以下关于堆栈溢出本身的问题,但对我来说并不清楚:

Spring CrudRepository:为什么要发明一种新的通用类型S

谢谢。

如果你把它作为

T save (T entity);

然后,您可以将结果分配给的唯一变量必须是 T 类型。

所以,如果你有一个CrudRepository<Animal,AnimalID> repository,你有

Dog dog = getDog();
Dog savedDog = repository.save(dog);

你会得到一个编译错误 - 你不能将结果分配给Dog,因为它必须是类型 T ,在这种情况下,Animal .

您需要检查返回的值是否确实是 Dog 类型,如果是,则将其转换为 Dog 以将其放入 savedDog 中。

使用声明,这意味着您可以将其分配给与原始参数类型相同的变量,因为类型解析将允许这样做。

声明本身并没有具体说明如何保存狗的非动物部分。它所做的只是允许将结果分配回Dog如果它最初是一个Dog

这是保存方法的上限示例,而程序员可能希望使用CrudRepository的实现来保留实体中的S。UpperBounds 限制可以传递给 save 方法的对象类型,在这种情况下,T 是通常由 CrudRepository 管理的实体的实例类型,这意味着只有这些实体的子实体或实现可以用作 S。

这篇文章突出显示了错误,但这篇文章显示了错误描述,清楚地讲述了这个故事。

最新更新