【发布时间】:2017-07-20 00:33:18
【问题描述】:
我正在使用这样的存储库使用 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可以比检查每个属性更好的方式根据对象属性返回交集?
已尝试通过硬编码(我之前从存储库 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
【问题讨论】:
-
有趣的问题。由于您正在定义调用什么方法的实际规则,因此您仍然需要遍历
CreditCardGetReq的所有属性 -
@Eugene,是的,我不在乎遍历所有属性是容易的部分,但是执行 findByX 组合是一个挑战。我会尝试构建一个动态字符串,例如“findByXAndY”动态并通过反射调用 repo 是否可以解决问题,但我觉得我在这里遗漏了一些东西
-
实际上我也在考虑这个方向......但是通过
MethodHandles,而不是反射,如果你有存储库的实际实例,这将起作用。问题是方法句柄显然需要它们的调用参数 -
@Eugene,已经尝试过 MethodHandle 但似乎它不起作用。也用这些细节更新了问题
-
我自己没有用过这个,但是
RedisCallback和RedisTemplate不会给你你想要的吗?虽然使用纯 Spring Data 会更抽象
标签: java spring redis spring-data spring-data-redis