我正在寻找Spring Data JPA。考虑下面的例子,我将得到所有的crud和查找器功能默认工作,如果我想自定义一个查找器,那么也可以在界面本身轻松完成。
@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {
@Query("<JPQ statement here>")
List<Account> findByCustomer(Customer customer);
}
我想知道如何添加一个完整的自定义方法及其实现以上AccountRepository?因为它是一个接口,我不能在那里实现方法。
公认的答案是可行的,但有三个问题:
在将自定义实现命名为AccountRepositoryImpl时,它使用了一个未记录的Spring Data特性。文档明确指出它必须被称为AccountRepositoryCustomImpl,即自定义接口名加上Impl
不能使用构造函数注入,只能使用@Autowired,这被认为是不好的做法
在自定义实现中有一个循环依赖(这就是为什么不能使用构造函数注入)。
我找到了一个让它变得完美的方法,尽管不是没有使用另一个未记录的Spring Data特性:
public interface AccountRepository extends AccountRepositoryBasic,
AccountRepositoryCustom
{
}
public interface AccountRepositoryBasic extends JpaRepository<Account, Long>
{
// standard Spring Data methods, like findByLogin
}
public interface AccountRepositoryCustom
{
public void customMethod();
}
public class AccountRepositoryCustomImpl implements AccountRepositoryCustom
{
private final AccountRepositoryBasic accountRepositoryBasic;
// constructor-based injection
public AccountRepositoryCustomImpl(
AccountRepositoryBasic accountRepositoryBasic)
{
this.accountRepositoryBasic = accountRepositoryBasic;
}
public void customMethod()
{
// we can call all basic Spring Data methods using
// accountRepositoryBasic
}
}
你需要为你的自定义方法创建一个单独的接口:
public interface AccountRepository
extends JpaRepository<Account, Long>, AccountRepositoryCustom { ... }
public interface AccountRepositoryCustom {
public void customMethod();
}
并为该接口提供一个实现类:
public class AccountRepositoryImpl implements AccountRepositoryCustom {
@Autowired
@Lazy
AccountRepository accountRepository; /* Optional - if you need it */
public void customMethod() { ... }
}
参见:
4.6 Spring数据存储库的自定义实现
请注意,不同版本之间的命名方案发生了变化。详情见https://stackoverflow.com/a/52624752/66686。
I扩展了SimpleJpaRepository:
public class ExtendedRepositoryImpl<T extends EntityBean> extends SimpleJpaRepository<T, Long>
implements ExtendedRepository<T> {
private final JpaEntityInformation<T, ?> entityInformation;
private final EntityManager em;
public ExtendedRepositoryImpl(final JpaEntityInformation<T, ?> entityInformation,
final EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityInformation = entityInformation;
this.em = entityManager;
}
}
并将这个类添加到@EnableJpaRepositoryries repositoryBaseClass中。
公认的答案是可行的,但有三个问题:
在将自定义实现命名为AccountRepositoryImpl时,它使用了一个未记录的Spring Data特性。文档明确指出它必须被称为AccountRepositoryCustomImpl,即自定义接口名加上Impl
不能使用构造函数注入,只能使用@Autowired,这被认为是不好的做法
在自定义实现中有一个循环依赖(这就是为什么不能使用构造函数注入)。
我找到了一个让它变得完美的方法,尽管不是没有使用另一个未记录的Spring Data特性:
public interface AccountRepository extends AccountRepositoryBasic,
AccountRepositoryCustom
{
}
public interface AccountRepositoryBasic extends JpaRepository<Account, Long>
{
// standard Spring Data methods, like findByLogin
}
public interface AccountRepositoryCustom
{
public void customMethod();
}
public class AccountRepositoryCustomImpl implements AccountRepositoryCustom
{
private final AccountRepositoryBasic accountRepositoryBasic;
// constructor-based injection
public AccountRepositoryCustomImpl(
AccountRepositoryBasic accountRepositoryBasic)
{
this.accountRepositoryBasic = accountRepositoryBasic;
}
public void customMethod()
{
// we can call all basic Spring Data methods using
// accountRepositoryBasic
}
}