Java 如何在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) {

根据Spring Data Commons,将自定义方法实现添加到Spring数据存储库非常简单:

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
。这更像是春意盎然。:-)