DATACOUCH-241 - Document mixing SpEL and N1QL placeholders

This commit is contained in:
Simon Baslé
2016-08-18 12:55:05 +02:00
parent 7863688028
commit 415d8a2d23
3 changed files with 37 additions and 2 deletions

View File

@@ -13,4 +13,10 @@ public interface SpelRepository extends CrudRepository<User, String> {
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND username = \"#{oneCustomer}\"")
List<User> findCustomUsers();
//notice how the SpEL syntax #{[0]} considers the first method argument,
//and N1QL placeholder resolution will still consider every method argument as a placeholder value.
//thus N1QL placeholder used is $2, to match criteriaValue
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND #{[0]} = $2")
List<User> findUserWithDynamicCriteria(String criteriaField, Object criteriaValue);
}

View File

@@ -16,11 +16,14 @@
package org.springframework.data.couchbase.repository.spel;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.*;
import java.util.List;
import com.couchbase.client.java.Bucket;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -66,4 +69,15 @@ public class SpelRepositoryTests {
assertEquals("uname-3", users.get(0).getUsername());
}
@Test
public void testSpelArgumentResolution() {
List<User> usersByName = repository.findUserWithDynamicCriteria("username", "uname-5");
List<User> usersByAge = repository.findUserWithDynamicCriteria("age", 4);
assertThat(usersByName, hasSize(1));
assertThat(usersByAge, hasSize(1));
assertThat(usersByName.get(0).getKey(), is("testuser-5"));
assertThat(usersByAge.get(0).getKey(), is("testuser-4"));
}
}

View File

@@ -147,10 +147,25 @@ IMPORTANT: We recommend that you always use the `selectEntity` SpEL and a WHERE
String-based queries support parametrized queries. You can either use positional placeholders like "`$1`", in which case each of the method parameters will map, in order, to `$1`, `$2`, `$3`... Alternatively, you can use named placeholders using the "`$someString`" syntax. Method parameters will be matched with their corresponding placeholder using the parameter's name, which can be overridden by annotating each parameter (except a `Pageable` or `Sort`) with `@Param` (eg. `@Param("someString")`). You cannot mix the two approaches in your query and will get an `IllegalArgumentException` if you do.
Note that you can mix N1QL placeholders and SpEL. N1QL placeholders will still consider all method parameters, so be sure to use the correct index like in the example below:
.An inline query that mixes SpEL and N1QL placeholders
====
[source,java]
----
@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND #{[0]} = $2")
public List<User> findUsersByDynamicCriteria(String criteriaField, Object criteriaValue)
----
====
This allows you to generate queries that would work similarly to eg. `AND name = "someName"` or `AND age = 3`, with a single method declaration.
You can also do single projections in your N1QL queries (provided it selects only one field and returns only one result, usually an aggregation like `COUNT`, `AVG`, `MAX`...). Such projection would have a simple return type like `long`, `boolean` or `String`. This is *NOT* intended for projections to DTOs.
Another example: "`#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND test = $1`", which is equivalent to
`SELECT #{#n1ql.fields} FROM #{#n1ql.bucket} WHERE #{#n1ql.filter} AND test = $1`".
Another example: +
`#{#n1ql.selectEntity} WHERE #{#n1ql.filter} AND test = $1` +
is equivalent to +
`SELECT #{#n1ql.fields} FROM #{#n1ql.bucket} WHERE #{#n1ql.filter} AND test = $1`
.A practical application of SpEL with Spring Security
****