Spring Data Couchbase 自定义存储库方法
Spring Data Couchbase custom repository method
大家好,我在使用 Spring Data Couchbase 上的 couchbase 模板添加简单的自定义查询时遇到问题。
存储库接口:
@RepositoryRestResource
public interface EmployeeRepository extends CouchbasePagingAndSortingRepository<Employee, String>, EmployeeCustomRepository {
}
public interface EmployeeCustomRepository {
List<Employee> customMethod(String firstName, String lastName);
}
实施
public class EmployeeRepositoryImpl implements EmployeeCustomRepository, InitializingBean {
@Autowired
private RepositoryOperationsMapping templateProvider;
private CouchbaseOperations template;
@Override
public void afterPropertiesSet() throws Exception {
template = templateProvider.resolve(EmployeeRepository.class, Employee.class);
}
@Override
public List<Employee> customMethod(String firstName, String lastName) {
N1qlQuery query = N1qlQuery.parameterized(
"SELECT * FROM " + template.getCouchbaseBucket().name() + " WHERE firstName = AND lastName = ",
JsonArray.from(firstName, lastName));
return template.findByN1QLProjection(query, Employee.class);
}
}
型号
@Data
@AllArgsConstructor
@Document
public class Employee {
@Id
private String id;
@Field
private String firstName;
@Field
private String lastName;
}
主要应用
@SpringBootApplication
public class SpringDataCouchbaseCustomExampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringDataCouchbaseCustomExampleApplication.class, args);
}
@Autowired
private EmployeeRepository repository;
@Override
public void run(String... strings) throws Exception {
String empId = "1";
Employee employee = repository.findOne(empId);
if(employee == null) {
employee = new Employee(empId, "Joe", "Smith");
repository.save(employee);
}
List<Employee> result = repository.customMethod("Joe", "Smith");
System.out.println("correct result:" + result.size());
result = repository.customMethod("Joe", "Wopa");
System.out.println("no result:" + result.size());
}
}
堆栈跟踪
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at com.example.SpringDataCouchbaseCustomExampleApplication.main(SpringDataCouchbaseCustomExampleApplication.java:14) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.4.3.RELEASE.jar:1.4.3.RELEASE]
Caused by: java.lang.RuntimeException: Cannot decode ad-hoc JSON
at org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService.decodeFragment(JacksonTranslationService.java:245) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at org.springframework.data.couchbase.core.CouchbaseTemplate.findByN1QLProjection(CouchbaseTemplate.java:466) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at com.example.EmployeeRepositoryImpl.customMethod(EmployeeRepositoryImpl.java:26) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:478) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:87) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at com.sun.proxy.$Proxy77.customMethod(Unknown Source) ~[na:na]
at com.example.SpringDataCouchbaseCustomExampleApplication.run(SpringDataCouchbaseCustomExampleApplication.java:31) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
... 11 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "default" (class com.example.Employee), not marked as ignorable (3 known properties: "lastName", "id", "firstName"])
at [Source: {"default":{"firstName":"Joe","lastName":"Smith","_class":"com.example.Employee"}}; line: 1, column: 83] (through reference chain: com.example.Employee["default"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:834) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1093) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1477) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperties(BeanDeserializerBase.java:1431) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:487) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1198) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842) ~[jackson-databind-2.8.5.jar:2.8.5]
at org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService.decodeFragment(JacksonTranslationService.java:242) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
... 33 common frames omitted
这是由于混合了您编写查询语句的方式和您在模板上使用的方法
首先,您正在尝试检索 Employee
个实体,它们是 fully-fledged 个实体。此 findByN1QLProjection
用于不同类型的查询,您只需要 select 几个字段,例如 count(*)
查询。
所以你应该改用findByN1ql
。无论如何,都存在一个问题:N1QL 为最简单(但也是最自然)形式的查询返回的格式不适用于 Jackson 的反序列化。
首先,N1QL 将每个结果包装在一个 JSON 对象中,其中包含一个以数据来自的存储桶命名的字段,此处为 "default")。这是您看到的问题:(
其次,为了反序列化实体,spring-data-couchbase 需要您的 N1QL 查询 select SELECT(*)
未涵盖的一些特定内容:meta-data(即ID
和CAS
)。
我们提供 N1qlUtils
class 来帮助解决这个问题......
请注意处理编写自定义方法的 section of the doc 如何在第 8 步使用 N1qlUtils
class 来构建查询?
我同意它有点误导,因为它使用了投影方法,所以你必须稍微调整一下才能使用 N1qlUtils.createSelectFromForEntity
和 N1qlUtils. createWhereFilterForEntity
。像这样:
// your own WHERE criteria:
Expression where = x("firstName = and lastName = ");
Statement statement =
//this will produce the adequate SELECT..FROM.. clause:
N1qlUtils.createSelectFromForEntity(template.getCouchbaseBucket().name())
//use the DSL to continue to the WHERE clause
.where(
//this will produce the adequate WHERE criterias in addition to your own:
//(see doc snippet for getting converter and entityInfo)
N1qlUtils.createWhereFilterForEntity(where, converter, entityInfo));
然后您可以从该语句(而不是字符串)创建一个 N1qlQuery
并使用 findByN1ql
...
执行它
快速替代:
您可以使用 string-based 查询推导。
查看 this test 示例。您可以在 EmployeeRepository
界面的注释中对 WHERE 子句进行一些调整,然后放置一个类似的签名(那里不需要自定义实现)。
大家好,我在使用 Spring Data Couchbase 上的 couchbase 模板添加简单的自定义查询时遇到问题。
存储库接口:
@RepositoryRestResource
public interface EmployeeRepository extends CouchbasePagingAndSortingRepository<Employee, String>, EmployeeCustomRepository {
}
public interface EmployeeCustomRepository {
List<Employee> customMethod(String firstName, String lastName);
}
实施
public class EmployeeRepositoryImpl implements EmployeeCustomRepository, InitializingBean {
@Autowired
private RepositoryOperationsMapping templateProvider;
private CouchbaseOperations template;
@Override
public void afterPropertiesSet() throws Exception {
template = templateProvider.resolve(EmployeeRepository.class, Employee.class);
}
@Override
public List<Employee> customMethod(String firstName, String lastName) {
N1qlQuery query = N1qlQuery.parameterized(
"SELECT * FROM " + template.getCouchbaseBucket().name() + " WHERE firstName = AND lastName = ",
JsonArray.from(firstName, lastName));
return template.findByN1QLProjection(query, Employee.class);
}
}
型号
@Data
@AllArgsConstructor
@Document
public class Employee {
@Id
private String id;
@Field
private String firstName;
@Field
private String lastName;
}
主要应用
@SpringBootApplication
public class SpringDataCouchbaseCustomExampleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringDataCouchbaseCustomExampleApplication.class, args);
}
@Autowired
private EmployeeRepository repository;
@Override
public void run(String... strings) throws Exception {
String empId = "1";
Employee employee = repository.findOne(empId);
if(employee == null) {
employee = new Employee(empId, "Joe", "Smith");
repository.save(employee);
}
List<Employee> result = repository.customMethod("Joe", "Smith");
System.out.println("correct result:" + result.size());
result = repository.customMethod("Joe", "Wopa");
System.out.println("no result:" + result.size());
}
}
堆栈跟踪
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
at com.example.SpringDataCouchbaseCustomExampleApplication.main(SpringDataCouchbaseCustomExampleApplication.java:14) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.4.3.RELEASE.jar:1.4.3.RELEASE]
Caused by: java.lang.RuntimeException: Cannot decode ad-hoc JSON
at org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService.decodeFragment(JacksonTranslationService.java:245) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at org.springframework.data.couchbase.core.CouchbaseTemplate.findByN1QLProjection(CouchbaseTemplate.java:466) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at com.example.EmployeeRepositoryImpl.customMethod(EmployeeRepositoryImpl.java:26) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:478) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.12.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.data.couchbase.repository.support.ViewPostProcessor$ViewInterceptor.invoke(ViewPostProcessor.java:87) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.5.RELEASE.jar:4.3.5.RELEASE]
at com.sun.proxy.$Proxy77.customMethod(Unknown Source) ~[na:na]
at com.example.SpringDataCouchbaseCustomExampleApplication.run(SpringDataCouchbaseCustomExampleApplication.java:31) [classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) [spring-boot-1.4.3.RELEASE.jar:1.4.3.RELEASE]
... 11 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "default" (class com.example.Employee), not marked as ignorable (3 known properties: "lastName", "id", "firstName"])
at [Source: {"default":{"firstName":"Joe","lastName":"Smith","_class":"com.example.Employee"}}; line: 1, column: 83] (through reference chain: com.example.Employee["default"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:62) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:834) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1093) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1477) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperties(BeanDeserializerBase.java:1431) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:487) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1198) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:314) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798) ~[jackson-databind-2.8.5.jar:2.8.5]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2842) ~[jackson-databind-2.8.5.jar:2.8.5]
at org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService.decodeFragment(JacksonTranslationService.java:242) ~[spring-data-couchbase-2.1.6.RELEASE.jar:na]
... 33 common frames omitted
这是由于混合了您编写查询语句的方式和您在模板上使用的方法
首先,您正在尝试检索 Employee
个实体,它们是 fully-fledged 个实体。此 findByN1QLProjection
用于不同类型的查询,您只需要 select 几个字段,例如 count(*)
查询。
所以你应该改用findByN1ql
。无论如何,都存在一个问题:N1QL 为最简单(但也是最自然)形式的查询返回的格式不适用于 Jackson 的反序列化。
首先,N1QL 将每个结果包装在一个 JSON 对象中,其中包含一个以数据来自的存储桶命名的字段,此处为 "default")。这是您看到的问题:(
其次,为了反序列化实体,spring-data-couchbase 需要您的 N1QL 查询 select SELECT(*)
未涵盖的一些特定内容:meta-data(即ID
和CAS
)。
我们提供 N1qlUtils
class 来帮助解决这个问题......
请注意处理编写自定义方法的 section of the doc 如何在第 8 步使用 N1qlUtils
class 来构建查询?
我同意它有点误导,因为它使用了投影方法,所以你必须稍微调整一下才能使用 N1qlUtils.createSelectFromForEntity
和 N1qlUtils. createWhereFilterForEntity
。像这样:
// your own WHERE criteria:
Expression where = x("firstName = and lastName = ");
Statement statement =
//this will produce the adequate SELECT..FROM.. clause:
N1qlUtils.createSelectFromForEntity(template.getCouchbaseBucket().name())
//use the DSL to continue to the WHERE clause
.where(
//this will produce the adequate WHERE criterias in addition to your own:
//(see doc snippet for getting converter and entityInfo)
N1qlUtils.createWhereFilterForEntity(where, converter, entityInfo));
然后您可以从该语句(而不是字符串)创建一个 N1qlQuery
并使用 findByN1ql
...
快速替代:
您可以使用 string-based 查询推导。
查看 this test 示例。您可以在 EmployeeRepository
界面的注释中对 WHERE 子句进行一些调整,然后放置一个类似的签名(那里不需要自定义实现)。