如何使用Spring Data Redis存储库构建动态查询?

时间:2017-02-28 21:17:31

标签: java spring redis spring-data spring-data-redis

我使用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

1 个答案:

答案 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来跟踪此功能的进度。