在Spring Data JPA基本仓库中按ID查找

3
我正在尝试在Spring Data JPA类的BaseRepository中实现一个通用的findByIdsIn方法,以便所有实现该接口的类都可以使用该功能。我对Spring Data JPA还不太熟悉,所以不确定是否可能以及如何实现。
以下是目前的代码。 findByIdsIn是我想要实现的功能。
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
    List<T> findAll( );
    Optional<T> findById(ID id);
    List<T> findByIdsIn(List<ID> ids); // This is the functionality I'd like to implement.
}

你们有什么建议吗?非常感谢!
2个回答

4
我刚找到一个我满意的解决方案:

@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
    List<T> findAll( );
    Optional<T> findById(ID id);
    @Query("SELECT t FROM #{#entityName} t WHERE t.id IN :ids")
    List<T> findByIdsIn(@Param("ids") List<ID> ids);
}

如果有更加优雅的解决方案,我非常欢迎其他人进行贡献。


需要在JPA中注册BaseRepository吗? - Adesh Kumar
@jimmy,你能否请接受这个问题的答案。 - Vinay Prajapati

0

默认情况下,SimpleJpaRepository是基本存储库操作的实现。您应该实现并编写一个继承SimpleJpaRepository的类。将两种类型参数作为传递给接口SimpleJpaRepository的实现的泛型类型。以下是符合您要求的示例实现:

import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.io.Serializable;
import java.util.Optional;

public class BaseRepositoryImpl <T, ID extends Serializable>
        extends SimpleJpaRepository<T, ID>  implements BaseRepository<T, ID> {

    private final EntityManager entityManager;

    public BaseRepositoryImpl(Class<T> domainClass, EntityManager entityManager) {
        super(domainClass, entityManager);
        this.entityManager = entityManager;
    }

    @Override
   public  List<T> findByIdsIn(List<ID> ids) {
        List<T> entities = entityManager.createQuery(
        "FROM"+this.getDomainClass()+" WHERE id IN ("+CommonUtils.concat(ids,',')+")").getResultList(); // concatenation code is not tested hence u need to fix it 
        return entities;
    }
}

此外,您需要覆盖默认实现,即 SimpleJpaRepository,使用您自己的实现,即 BaseRepositoryImpl
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

import javax.persistence.EntityManager;
import java.io.Serializable;

public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T,
        I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new BaseRepositoryFactory(entityManager);
    }

    private static class BaseRepositoryFactory<T, I extends Serializable>
            extends JpaRepositoryFactory {

        private final EntityManager entityManager;

        public BaseRepositoryFactory(EntityManager entityManager) {
            super(entityManager);
            this.entityManager = entityManager;
        }

        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {
            return new BaseRepositoryImpl<T, I>((Class<T>) metadata.getDomainType(), entityManager);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            return BaseRepositoryImpl.class;
        }
    }
}

最后,在Spring配置中使用@EnableJpaRepositories注释并指定以下类来配置您的BaseRepositoryFactoryBean。这将告诉JPA调用哪个RepositoryFactoryBean,并进而告诉哪个JPA存储库在整个过程中使用它,并使用其Impl类初始化它的实现。
@EnableJpaRepositories(basePackages = {"com.test.jpa.custom.repository"},
        repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)
class Configuration{}

现在你可以使用BaseRepository,并且findByIdsIn将在整个应用程序中可用。


我已经尽力提供了足够的代码来帮助您创建自定义存储库。但是还应该有一些有用的链接,详细解释为什么需要这么多步骤。 - Vinay Prajapati
谁给我点了踩,能否请您帮我理解一下这篇文章的问题。 - Vinay Prajapati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接