我使用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个属性,所以&#39;如果&#39;链是不可能的。
我想问你如何使用spring-data-redis创建动态查询,因此Redis可以比检查每个属性更好地返回基于对象属性的交集?
尝试通过硬编码(我之前从存储库findByIssuerAndCreditNetwork
中删除)使用MethodHandle,这是一个动态生成的方法名称,如下所示:
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:没有这样的方法:com.creditcard.dao.CreditCardRepository.findByIssuerAndCreditNetwork(String,String)ArrayList / invokeInterface
答案 0 :(得分:2)
目前,我们不支持创建动态查询。听起来好像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来跟踪此功能的进度。