我尝试使用@Query
N1QL查询语法注入除值之外的任何内容但无法使其工作。
以下是纯N1QL查询:
SELECT * from `my-bucket` WHERE _class = 'my.package.MyModel' AND myParam = 'myValue'
我成功地设法在Java中注入值并获得正确的结果:
// In my repository
@Query("#{#n1ql.selectEntity} WHERE myParam = $1 AND #{#n1ql.filter}")
Collection<MyModel> myCustomSearch(String value);
// In my business code
myRepository.myCustomSearch("myValue");
然而,我无法注入其他任何内容(如param)。这不起作用:
// In my repository
@Query("#{#n1ql.selectEntity} WHERE $1 = 'myValue' AND #{#n1ql.filter}")
Collection<MyModel> myCustomSearch(String param);
// In my business code
myRepository.myCustomSearch("myParam");
考虑到在纯粹的N1QL查询中,该值通常用单引号括起来(&#39;&#39;)注入时不需要它,我担心spring-data -couchbase总是用单引号或双引号包装注入的元素(因此我的查询转换为
SELECT * from `my-bucket` WHERE _class = 'my.package.MyModel' AND 'myParam' = 'myValue'
这解释了为什么Couchbase没有返回任何结果。
我错过了什么吗?否则,有没有办法绕过spring-data-couchbase的引用注入?
我知道我可以简单地使用com.couchbase.client.java.Bucket
并在其上调用query
,但这对我来说总是失去了spring-data-couchbase的全部意义,即总是操纵POJO并隐藏JSON操作。
我感谢任何帮助!
答案 0 :(得分:0)
编辑:请参阅@ simon-baslé的答案,比我的更短,更优雅。
我认为我以implementing a custom method in my repository的形式找到了满足我需求的最佳解决方案。
public interface MyRepositoryCustom {
Collection<MyModel> customN1qlQuery(String query);
}
public interface MyRepository extends CrudRepository<MyModel, String>, MyRepositoryCustom { }
public class MyRepositoryImpl implements MyRepositoryCustom {
@Autowired
RepositoryOperationsMapping templateProvider;
@Override
public Collection<MyModel> customN1qlQuery(String query) {
CouchbaseOperations template = templateProvider.resolve(MyRepository.class, MyModel.class);
return template.findByN1QL(N1qlQuery.simple(query), MyModel.class);
}
}
// In my business code
Collection<MyModel> result = myRepository.customN1qlQuery("select META().id AS _ID, META().cas AS _CAS, * from `" + bucket.name() + "` where _class = '"
+ MyModel.class.getCanonicalName() + "' and " + myCustomParam + " = '" + myCustomValue + "'");
我一直在操纵POJO,但我可以完全控制N1QL查询语句。唯一(次要)缺点是我不能再注入Spring SpEL syntax(如#{#n1ql.selectEntity}
来检索完整实体,或#{#n1ql.filter}
来过滤实体类名称)。我找到了字面上的等价物(如上面的例子中所示),所以我可以忍受它。
答案 1 :(得分:0)
$1
实际上只是将N1QL语法用于参数化语句。我还没有对它进行过广泛的测试,但你可以在这里使用SpEL。在SpEL中使用方法参数的方法是使用#{[x]}
语法,其中x
是要使用的参数的从0开始的索引。
在混合使用这两种方法时要小心:只要在语句中检测到$x
,Spring Data Couchbase就会使用所有方法参数作为数组来填充$ x占位符。因此,第一个参数将映射到$1
,第二个参数映射到$2
等等......
因此,要使用两种语法(一种用于动态选择字段名称,另一种用于让N1QL注入搜索值),您必须编写如下内容:
@Query("#{#n1ql.selectEntity} WHERE #{[0]} = $2 AND #{#n1ql.filter}")
public List<Entity> findAllBySomeCriteria(String fieldName, String value);
请注意#{[0]}
和$1
如何指向fieldName
参数,因此使用的N1QL占位符为$2
,指向value
。< / p>