英文:
How can I override Spring repository methods to add a constraint on a boolean column?
问题
我正在阅读《Spring In Action》(第6版),以便学习Spring框架,我有一个关于如何覆盖Spring JPA默认行为的疑问,当声明存储库时。
据我迄今为止所读,我可以声明存储库方法,比如findByName()
,然后让Spring神奇地实现这个方法。现在,让我们想象一下,存储库中的记录有一个名为enabled
的布尔列,我希望应用程序只处理enabled = TRUE
的记录。我知道我可以声明诸如findByNameAndEnabledIsTrue()
之类的方法,但我想知道是否有一种方法可以使例如findByName()
考虑到这个标志。
到目前为止,我尝试覆盖该方法,但似乎不起作用,因为在编译时实际上没有定义方法:
@Override
List<Customer> findByName(@Param("name") String name) {
return findByNameAndEnabledIsTrue(name);
}
这该怎么做呢?
谢谢。
英文:
I am reading Spring In Action (6th edition) to get myself into learning the Spring framework and I have a doubt about how to override the default behavior of Spring JPA when declaring repositories.
As far as I have read so far, I can declare repository methods such as findByName()
and let Spring magically implement the method. Now, let's imagine that the records in the repository have a boolean column named enabled
, and I want the application to only process the records with enabled = TRUE
. I know I could declare methods such as findByNameAndEnabledIsTrue()
but I wonder whether there is a way to make, for example, findByName()
take into account this flag.
So far I tried to override the method, but it doesn't seem to work, since there's actual no method defined at compile time:
@Override
List<Customer> findByName(@Param("name") String name) {
return findByNameAndEnabledIsTrue(name);
}
How could this be done?
Thank you.
答案1
得分: 1
最简单的方法是使用@Query
来明确定义查询,使用JPQL而不是依赖spring-data根据查询方法名称生成查询。通过这种方式,您可以完全控制定义您想要的查询。类似于:
public interface CustomerRepository extends JpaRepository<Customer, Long> {
@Query("select u from Customer c where c.name = :name and c.enabled = true")
List<Customer> findByName(@Param("name") String name);
}
这是我喜欢的方式。简单、灵活,减少了很多魔法。
如果您坚持不想编写JPQL,您可以实现一个自定义存储库(参见此处),并将CustomerRepository
注入到这个自定义存储库中,以重用其方法。类似于:
interface CustomerRepository extends JpaRepository<Customer, Long>, CustomizedCustomerRepository {
List<Customer> findByNameAndEnabledIsTrue();
}
interface CustomizedCustomerRepository {
void findByName(String name);
}
class CustomizedCustomerRepositoryImpl implements CustomizedCustomerRepository {
@Autowired
private CustomerRepository repo;
@Override
List<Customer> findByName(String name) {
return repo.findByNameAndEnabledIsTrue(name);
}
}
英文:
The simplest way is to use @Query
to explicitly define the query using JPQL rather than relies on spring-data to generate the query based on the query method name. In this way, you can get back the total control to define what the query you exactly want to have . Something like :
public interface CustomerRepository extends JpaRepository<Customer, Long> {
@Query("select u from Customer c where c.name = :name and c.enabled = true")
List<Customer> findByName(@Param("name") String name);
}
This is the way I prefer. Simple, flexible and much less magic.
If you insist do not want to write JPQL, you can implement a custom repository (See this) , and inject the CustomerRepository
into this custom repository and reuse it method. Something like :
interface CustomerRepository extends JpaRepository<Customer, Long> , CustomizedCustomerRepository {
List<Customer> findByNameAndEnabledIsTrue();
}
interface CustomizedCustomerRepository {
void findByName(String name);
}
class CustomizedCustomerRepositoryImpl implements CustomizedCustomerRepository {
@Autowired
private CustomerRepository repo;
@Override
List<Customer> findByName(String name) {
return repo.findByNameAndEnabledIsTrue(name);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论