我正在寻找Spring Data JPA。考虑下面的例子,我将得到所有的crud和查找器功能默认工作,如果我想自定义一个查找器,那么也可以在界面本身轻松完成。

@Transactional(readOnly = true)
public interface AccountRepository extends JpaRepository<Account, Long> {

  @Query("<JPQ statement here>")
  List<Account> findByCustomer(Customer customer);
}

我想知道如何添加一个完整的自定义方法及其实现以上AccountRepository?因为它是一个接口,我不能在那里实现方法。


当前回答

考虑到您的代码片段,请注意,您只能将本机对象传递给findBy###方法,假设您想要加载属于某些客户的帐户列表,一个解决方案是这样做,

@Query("Select a from Account a where a."#nameoffield"=?1")
List<Account> findByCustomer(String "#nameoffield");

确保要查询的表的名称与Entity类相同。 关于进一步的实现,请看看这个

其他回答

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中。

你需要为你的自定义方法创建一个单独的接口:

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。

这里还有一个问题需要考虑。有些人希望将自定义方法添加到存储库中将自动将其作为'/search'链接下的REST服务公开。不幸的是,事实并非如此。Spring目前不支持这一点。

这是“设计”特性,spring data rest显式检查方法是否为自定义方法,并且不会将其作为rest搜索链接公开:

private boolean isQueryMethodCandidate(Method method) {    
  return isQueryAnnotationPresentOn(method) || !isCustomMethod(method) && !isBaseClassMethod(method);
}

这是Oliver Gierke的一段话:

这是有意为之。自定义存储库方法不像查询方法那样 它们可以有效地实现任何行为。因此,它目前是 我们不可能决定HTTP方法来公开方法 下。POST是最安全的选择但这与 泛型查询方法(接收GET)。

欲了解更多详细信息,请参阅此问题:https://jira.spring.io/browse/DATAREST-206

考虑到您的代码片段,请注意,您只能将本机对象传递给findBy###方法,假设您想要加载属于某些客户的帐户列表,一个解决方案是这样做,

@Query("Select a from Account a where a."#nameoffield"=?1")
List<Account> findByCustomer(String "#nameoffield");

确保要查询的表的名称与Entity类相同。 关于进一步的实现,请看看这个

我使用SimpleJpaRepository作为存储库实现的基类,并在接口中添加自定义方法,例如:

public interface UserRepository  {
    User FindOrInsert(int userId);
}

@Repository
public class UserRepositoryImpl extends SimpleJpaRepository implements UserRepository {

    private RedisClient redisClient;

    public UserRepositoryImpl(RedisClient redisClient, EntityManager em) {
        super(User.class, em);
        this.redisClient = redisClient;
    }


@Override
public User FindOrInsert(int userId) {

    User u = redisClient.getOrSet("test key.. User.class, () -> {
        Optional<User> ou = this.findById(Integer.valueOf(userId));
        return ou.get();
    });
    …………
    return u;
}