首页 文章

Spring Data JPA如何为多个实体构建通用存储库? [重复]

提问于
浏览
0

这个问题在这里已有答案:

我开始使用Spring Data JPA存储库 . 我们有一个已经使用Spring MVC的应用程序(No spring boot或spring data JPA),我们已经编写了一个Generic DAO类,它可以为我们拥有的几乎所有实体处理基本的CRUD操作 . 可以通过编写自定义DAO来处理任何其他特殊操作 .

现在,Spring数据JPA通过要求我们只编写一个接口而其余部分得到处理,使事情变得非常容易 .

public interface PersonRepository extends JpaRepository<Person, Long> {

}

这很酷,但我想知道我是否可以在这里介绍泛型 .

原因是,我的应用程序有许多实体,我们只需要执行基本的CRUD操作,仅此而已 . 这意味着,对于每个实体,我们都需要编写一个接口 . 尽管代码很小,但它会为每个实体生成一个文件,我想这是可以避免的(是吗?) .

我的问题是,我可以编写一个通用的Repository类吗?

public interface GenericRepository<T> extends JpaRepository<T, Long> {

}

这样我的服务类就像这样

@Autowired
private GenericRepository<Person> personRepository;

public List<Person> findAll() {
     return this.personRepository.findAll();
}

对于基本操作,这将是一种更清晰的方法,因为一个Repository接口处理许多实体 .

EDIT 事实证明我确实可以创建一个存储库接口,如上所示,但是当应用程序启动时,我收到一个错误,

Error creating bean with name 'genericRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Object

这可能是因为通用类型

我不得不说我的实体本身就是单独的类,并且不实现或扩展超级实体/实体 . 如果他们这样做会有帮助吗?

请指导我正确的方向 .

谢谢!

1 回答

  • 0

    我想你可以这样做:

    @NoRepositoryBean
    public interface GenericRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
       //added custom common functionality for all the GenericRepository implementations
       public List<T> findByAttributeContainsText(String attributeName, String text);
    }
    
    public class GenericRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
        implements GenericRepository<T, ID> {
    
       private EntityManager entityManager;
    
       public GenericRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }
    
    @Transactional
    public List<T> findByAttributeContainsText(String attributeName, String text) {
        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<T> cQuery = builder.createQuery(getDomainClass());
        Root<T> root = cQuery.from(getDomainClass());
        cQuery.select(root).where(builder.like(root.<String>get(attributeName), "%" + text + "%"));
        TypedQuery<T> query = entityManager.createQuery(cQuery);
        return query.getResultList();
    }
    }
    public interface MyOtherRepository extends GenericRepository<Role, Long> {
    
    }
    

    在您的配置类中:

    @Configuration
    @EnableJpaRepositories(basePackages="com.myProject", repositoryBaseClass = 
    GenericRepositoryImpl.class)
    public class JpaConfig {
    
    }
    

相关问题