在Spring Repository中< S扩展T>SAVE(S实体);是什么意思?

3lxsmp7m  于 2022-09-18  发布在  Spring
关注(0)|答案(2)|浏览(128)

在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);

我已经在谷歌上搜索了更多的帮助,我已经想出了关于Stackoverflow本身的以下问题,但对我来说并不是很清楚:

Spring CrudRepository: why to invent a new generic type S

谢谢。

mspsb9vt

mspsb9vt1#

如果你把它当做

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)。

35g0bw71

35g0bw712#

这是一个保存方法的上限的例子,而实体中的S程序员可能希望使用CrudRepository的实现来持久化。UpperBound限制可以传递给保存方法的对象类型,本例中的T是CrudRepository的示例类型,这意味着只有CrudRepository的子级或实现可以用作S。

post突出显示了错误,但one显示了错误描述,清楚地说明了情况。

相关问题