Java 如何在Spring数据自定义方法实现中使用类型参数?
根据Spring Data Commons,将自定义方法实现添加到Spring数据存储库非常简单:Java 如何在Spring数据自定义方法实现中使用类型参数?,java,spring,repository,spring-data,spring-data-jpa,Java,Spring,Repository,Spring Data,Spring Data Jpa,根据Spring Data Commons,将自定义方法实现添加到Spring数据存储库非常简单: interface UserRepositoryCustom { public void someCustomMethod(User user); } class UserRepositoryCustomImpl implements UserRepositoryCustom { public void someCustomMethod(User user) {
interface UserRepositoryCustom {
public void someCustomMethod(User user);
}
class UserRepositoryCustomImpl implements UserRepositoryCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
public interface UserRepository extends JpaRepository<User, Long>,
UserRepositoryCustom {
}
interface UserRepositoryCustom{
公共方法(用户);
}
类UserRepositoryCustomImpl实现UserRepositoryCustom{
公共void方法(用户){
//您的自定义实现
}
}
公共接口用户存储库扩展了JpaRepository,
UserRepositoryCustom{
}
但是,我不明白的是,如果您想使用类型参数怎么办?例如:
interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class SearchableRepositoryImpl<T> implements SearchableRepository<T> {
public Page<T> search(String query, Pageable page) {
// Right here, I need the Class<T> of T so that I can create
// the JPA query
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> {
}
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> {
}
接口SearchableRepository{
公共页面搜索(字符串查询、可分页页面);
}
类SearchableRepositoryImpl实现SearchableRepository{
公共页面搜索(字符串查询、可分页页面){
//在这里,我需要T类,这样我就可以创建
//JPA查询
}
}
公共接口用户存储库扩展了JpaRepository,
可搜索存储库{
}
公共接口NewsRepository扩展了JpaRepository,因为我不希望所有存储库都可以搜索。我只想应用SearchableRepository
界面来选择存储库
那你怎么做呢?或者您可以这样做吗?您可以将类添加到SearchableRepositoryImpl,并在NewsRepositoryImpl中注入(或创建)一个新的SearchableRepositoryImpl(Article.Class)
类SearchableRepositoryImpl实现SearchableRepository{
私家级卡拉斯;
公共可搜索的RepositoryImpl(klazz类){
this.klass=klazz;
}
公共页面搜索(字符串查询、可分页页面){
//在这里,我需要T类,这样我就可以创建
//JPA查询
}
}
类NewsRepositoryImpl实现NewsRepository
{
private SearchableRepository searchRepo=新的SearchableRepositoryImpl(Article.class);
公共页面搜索(字符串查询、可分页页面){
//委派
返回searchRepo.search(查询,第页);
}
}
也许新的SearchableRepositoryImpl并不是spring的最佳实践,但仅仅是为了表明这一想法Bellabax的答案是正确的,让我走上了正确的轨道,所以他得到了正确答案的赞誉和赞誉。但是对于那些在这个问题上遇到障碍的人,这里有一个更完整的实现,它可以自动发现域类型,并且不需要调用new
任何东西,希望能对某些人有所帮助
SearchableRepository.java
public interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class AbstractDomainClassAwareRepository<T> {
protected final Class<T> domainClass;
@SuppressWarnings("unchecked")
protected AbstractDomainClassAwareRepository() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
while(!(genericSuperclass instanceof ParameterizedType))
{
if(!(genericSuperclass instanceof Class))
throw new IllegalStateException("Unable to determine type " +
"arguments because generic superclass neither " +
"parameterized type nor class.");
if(genericSuperclass == AbstractDomainClassAwareRepository.class)
throw new IllegalStateException("Unable to determine type " +
"arguments because no parameterized generic superclass " +
"found.");
genericSuperclass = ((Class)genericSuperclass).getGenericSuperclass();
}
ParameterizedType type = (ParameterizedType)genericSuperclass;
Type[] arguments = type.getActualTypeArguments();
this.domainClass = (Class<T>)arguments[0];
}
}
class AbstractSearchableJpaRepository<T>
extends AbstractDomainClassAwareRepository<T>
implements SearchableRepository<T> {
@PersistenceContext protected EntityManager entityManager;
@Override
public Page<T> search(String query, Pageable page) {
// use this.domainClass to reference domain class
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> { }
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> { }
公共界面SearchableRepository{
公共页面搜索(字符串查询、可分页页面);
}
AbstractDomainClassAwareRepository.java
public interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class AbstractDomainClassAwareRepository<T> {
protected final Class<T> domainClass;
@SuppressWarnings("unchecked")
protected AbstractDomainClassAwareRepository() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
while(!(genericSuperclass instanceof ParameterizedType))
{
if(!(genericSuperclass instanceof Class))
throw new IllegalStateException("Unable to determine type " +
"arguments because generic superclass neither " +
"parameterized type nor class.");
if(genericSuperclass == AbstractDomainClassAwareRepository.class)
throw new IllegalStateException("Unable to determine type " +
"arguments because no parameterized generic superclass " +
"found.");
genericSuperclass = ((Class)genericSuperclass).getGenericSuperclass();
}
ParameterizedType type = (ParameterizedType)genericSuperclass;
Type[] arguments = type.getActualTypeArguments();
this.domainClass = (Class<T>)arguments[0];
}
}
class AbstractSearchableJpaRepository<T>
extends AbstractDomainClassAwareRepository<T>
implements SearchableRepository<T> {
@PersistenceContext protected EntityManager entityManager;
@Override
public Page<T> search(String query, Pageable page) {
// use this.domainClass to reference domain class
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> { }
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> { }
class AbstractDomainClassAwareRepository{
受保护的最终类domainClass;
@抑制警告(“未选中”)
受保护的AbstractDomainClassAwareRepository(){
类型genericSuperclass=this.getClass().getGenericSuperclass();
while(!(参数化类型的genericSuperclass实例))
{
if(!(genericSuperclass实例of Class))
抛出新的IllegalStateException(“无法确定类型”+
“参数,因为泛型超类都不是”+
“参数化类型或类。”);
if(genericSuperclass==AbstractDomainClassAwareRepository.class)
抛出新的IllegalStateException(“无法确定类型”+
“参数,因为没有参数化泛型超类”+
“找到了。”);
genericSuperclass=((类)genericSuperclass.getGenericSuperclass();
}
ParameteredType type=(ParameteredType)genericSuperclass;
Type[]arguments=Type.getActualTypeArguments();
this.domainClass=(类)参数[0];
}
}
AbstractSearchableJpaRepository.java
public interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class AbstractDomainClassAwareRepository<T> {
protected final Class<T> domainClass;
@SuppressWarnings("unchecked")
protected AbstractDomainClassAwareRepository() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
while(!(genericSuperclass instanceof ParameterizedType))
{
if(!(genericSuperclass instanceof Class))
throw new IllegalStateException("Unable to determine type " +
"arguments because generic superclass neither " +
"parameterized type nor class.");
if(genericSuperclass == AbstractDomainClassAwareRepository.class)
throw new IllegalStateException("Unable to determine type " +
"arguments because no parameterized generic superclass " +
"found.");
genericSuperclass = ((Class)genericSuperclass).getGenericSuperclass();
}
ParameterizedType type = (ParameterizedType)genericSuperclass;
Type[] arguments = type.getActualTypeArguments();
this.domainClass = (Class<T>)arguments[0];
}
}
class AbstractSearchableJpaRepository<T>
extends AbstractDomainClassAwareRepository<T>
implements SearchableRepository<T> {
@PersistenceContext protected EntityManager entityManager;
@Override
public Page<T> search(String query, Pageable page) {
// use this.domainClass to reference domain class
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> { }
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> { }
class AbstractSearchableJpaRepository
扩展AbstractDomainClassAwareRepository
实现SearchableRepository{
@PersistenceContext保护的EntityManager EntityManager;
@凌驾
公共页面搜索(字符串查询、可分页页面){
//使用this.domainClass引用域类
}
}
UserRepository.java
public interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class AbstractDomainClassAwareRepository<T> {
protected final Class<T> domainClass;
@SuppressWarnings("unchecked")
protected AbstractDomainClassAwareRepository() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
while(!(genericSuperclass instanceof ParameterizedType))
{
if(!(genericSuperclass instanceof Class))
throw new IllegalStateException("Unable to determine type " +
"arguments because generic superclass neither " +
"parameterized type nor class.");
if(genericSuperclass == AbstractDomainClassAwareRepository.class)
throw new IllegalStateException("Unable to determine type " +
"arguments because no parameterized generic superclass " +
"found.");
genericSuperclass = ((Class)genericSuperclass).getGenericSuperclass();
}
ParameterizedType type = (ParameterizedType)genericSuperclass;
Type[] arguments = type.getActualTypeArguments();
this.domainClass = (Class<T>)arguments[0];
}
}
class AbstractSearchableJpaRepository<T>
extends AbstractDomainClassAwareRepository<T>
implements SearchableRepository<T> {
@PersistenceContext protected EntityManager entityManager;
@Override
public Page<T> search(String query, Pageable page) {
// use this.domainClass to reference domain class
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> { }
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> { }
public interface UserRepository扩展了JpaRepository,
SearchableRepository{}
UserRepositoryImpl.java
public class UserRepositoryImpl extends AbstractSearchableJpaRepository<User> { }
public class NewsRepositoryImpl extends AbstractSearchableJpaRepository<Article> { }
公共类UserRepositoryImpl扩展了AbstractSearchableJpaRepository{}
NewsRepository.java
public interface SearchableRepository<T> {
public Page<T> search(String query, Pageable page);
}
class AbstractDomainClassAwareRepository<T> {
protected final Class<T> domainClass;
@SuppressWarnings("unchecked")
protected AbstractDomainClassAwareRepository() {
Type genericSuperclass = this.getClass().getGenericSuperclass();
while(!(genericSuperclass instanceof ParameterizedType))
{
if(!(genericSuperclass instanceof Class))
throw new IllegalStateException("Unable to determine type " +
"arguments because generic superclass neither " +
"parameterized type nor class.");
if(genericSuperclass == AbstractDomainClassAwareRepository.class)
throw new IllegalStateException("Unable to determine type " +
"arguments because no parameterized generic superclass " +
"found.");
genericSuperclass = ((Class)genericSuperclass).getGenericSuperclass();
}
ParameterizedType type = (ParameterizedType)genericSuperclass;
Type[] arguments = type.getActualTypeArguments();
this.domainClass = (Class<T>)arguments[0];
}
}
class AbstractSearchableJpaRepository<T>
extends AbstractDomainClassAwareRepository<T>
implements SearchableRepository<T> {
@PersistenceContext protected EntityManager entityManager;
@Override
public Page<T> search(String query, Pageable page) {
// use this.domainClass to reference domain class
}
}
public interface UserRepository extends JpaRepository<User, Long>,
SearchableRepository<User> { }
public interface NewsRepository extends JpaRepository<Article, Long>,
SearchableRepository<Article> { }
public interface NewsRepository扩展了JpaRepository,
SearchableRepository{}
NewsRepositoryImpl.java
public class UserRepositoryImpl extends AbstractSearchableJpaRepository<User> { }
public class NewsRepositoryImpl extends AbstractSearchableJpaRepository<Article> { }
公共类NewsRepositoryImpl扩展了AbstractSearchableJpaRepository{}
Ahhh。我误解了定制的工作原理。这为我澄清了一切。谢谢我在下面添加了一个更完整的解决方案,它不需要如您所示的new
。这更像是春意盎然。:-)