如何使用 Spring Data Redis 存储库构建动态查询?
How to build dynamic queries with Spring Data Redis Repositories?
我正在使用 spring-data-redis 使用这样的存储库测试 Redis:
public interface CreditCardRepository extends CrudRepository<CreditCard, String>{
List<CreditCard> findByIssuer(String issuer);
List<CreditCard> findByCreditNetwork(String creditNetwork);
List<CreditCard> findByCreditNetworkAndIssuer(String creditNetwork, String issuer);
}
以上方法将查询像这样的 Redis 结构:
creditcard:creditNetwork:mastercard
creditcard:creditNetwork:visa
creditcard:issuer:company1
creditcard:issuer:company2
现在我的 CreditCard 对象包含两个属性(issuer、network 和 id),所以很容易搜索这样的对象:
private List<CreditCard> searchCardFromCache(CreditCardGetReq req) {
if (req.getIssuer() != null && req.getNetwork() != null) {
return ccRepository.findByIssuerAndCreditNetwork(req.getIssuer(), req.getNetwork().name());
}
if (req.getIssuer() != null) {
return ccRepository.findByIssuer(req.getIssuer());
}
if (req.getNetwork() != null) {
return ccRepository.findByCreditNetwork(req.getNetwork().name());
}
return null;
}
但是,我不喜欢这段代码,因为我必须创建所有属性的组合并且会非常混乱。将来我打算有 15 个属性,所以 'if' 链是不可能的。
我想问你如何使用 spring-data-redis 创建动态查询,这样 Redis 可以 return 基于对象属性的交集比检查每个更好的方式属性?
已尝试通过硬编码使用 MethodHandle(我之前从存储库中删除 findByIssuerAndCreditNetwork
)方法名称将动态生成,如下所示:
MethodType methodType = MethodType.methodType(cardList.getClass(), String.class, String.class);
// Dynamic create 'findByIssuerAndCreditNetwork'
MethodHandle methodHandle = MethodHandles.lookup().findVirtual(CreditCardRepository.class, "findByIssuerAndCreditNetwork", methodType);
但似乎 MethodHandle 不起作用,因为我遇到以下错误:
java.lang.NoSuchMethodException: no such method: com.creditcard.dao.CreditCardRepository.findByIssuerAndCreditNetwork(String,String)ArrayList/invokeInterface
目前不支持创建动态查询。听起来好像 Query by Example 可能就是您要找的东西。 Spring Data MongoDB 和 Spring Data JPA 已经实现了 Query by Example。
数据存储模块创建查询以匹配示例域对象:
Person person = new Person();
person.setFirstname("Dave");
Example<Person> example = Example.of(person);
MongoRepository repo = …
List<Person> result = repo.findAll(example); // returns all objects that with Dave in firstname
Spring Data Redis 目前不支持示例查询,但应该可以提供基本支持。
我创建了一个工单 DATAREDIS-605 来跟踪此功能的进度。
我正在使用 spring-data-redis 使用这样的存储库测试 Redis:
public interface CreditCardRepository extends CrudRepository<CreditCard, String>{
List<CreditCard> findByIssuer(String issuer);
List<CreditCard> findByCreditNetwork(String creditNetwork);
List<CreditCard> findByCreditNetworkAndIssuer(String creditNetwork, String issuer);
}
以上方法将查询像这样的 Redis 结构:
creditcard:creditNetwork:mastercard
creditcard:creditNetwork:visa
creditcard:issuer:company1
creditcard:issuer:company2
现在我的 CreditCard 对象包含两个属性(issuer、network 和 id),所以很容易搜索这样的对象:
private List<CreditCard> searchCardFromCache(CreditCardGetReq req) {
if (req.getIssuer() != null && req.getNetwork() != null) {
return ccRepository.findByIssuerAndCreditNetwork(req.getIssuer(), req.getNetwork().name());
}
if (req.getIssuer() != null) {
return ccRepository.findByIssuer(req.getIssuer());
}
if (req.getNetwork() != null) {
return ccRepository.findByCreditNetwork(req.getNetwork().name());
}
return null;
}
但是,我不喜欢这段代码,因为我必须创建所有属性的组合并且会非常混乱。将来我打算有 15 个属性,所以 'if' 链是不可能的。
我想问你如何使用 spring-data-redis 创建动态查询,这样 Redis 可以 return 基于对象属性的交集比检查每个更好的方式属性?
已尝试通过硬编码使用 MethodHandle(我之前从存储库中删除 findByIssuerAndCreditNetwork
)方法名称将动态生成,如下所示:
MethodType methodType = MethodType.methodType(cardList.getClass(), String.class, String.class);
// Dynamic create 'findByIssuerAndCreditNetwork'
MethodHandle methodHandle = MethodHandles.lookup().findVirtual(CreditCardRepository.class, "findByIssuerAndCreditNetwork", methodType);
但似乎 MethodHandle 不起作用,因为我遇到以下错误:
java.lang.NoSuchMethodException: no such method: com.creditcard.dao.CreditCardRepository.findByIssuerAndCreditNetwork(String,String)ArrayList/invokeInterface
目前不支持创建动态查询。听起来好像 Query by Example 可能就是您要找的东西。 Spring Data MongoDB 和 Spring Data JPA 已经实现了 Query by Example。
数据存储模块创建查询以匹配示例域对象:
Person person = new Person();
person.setFirstname("Dave");
Example<Person> example = Example.of(person);
MongoRepository repo = …
List<Person> result = repo.findAll(example); // returns all objects that with Dave in firstname
Spring Data Redis 目前不支持示例查询,但应该可以提供基本支持。
我创建了一个工单 DATAREDIS-605 来跟踪此功能的进度。