在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。
这篇文章突出显示了错误,但这篇文章显示了错误描述,清楚地讲述了这个故事。