Customized query binding for spring-data.
This is a sample project showing how it works.
This project is inspired from darrachequesne/spring-data-jpa-datatables, which works with spring-data-jpa.
A short but working example.
TODO Not uploaded to any public Maven Repository yet.
<dependency>
<groupId>com.eaphonetech</groupId>
<artifactId>eaphone-spring-data-query-jpa</artifactId>
<version>2.0.1</version>
</dependency>OR for MongoDB:
<dependency>
<groupId>com.eaphonetech</groupId>
<artifactId>eaphone-spring-data-query-mongodb</artifactId>
<version>2.0.1</version>
</dependency>In any @Configuration class, add:
@EnableMongoRepositories(repositoryFactoryBeanClass = EaphoneQueryRepositoryFactoryBean.class)Just as spring-data does:
@Repository
public interface UserRepository extends JpaQueryRepository<Order, Long> {
}OR for MongoDB:
@Repository
public interface UserRepository extends MongoDBQueryRepository<Order, String> {
}Note that EaphoneQueryRepository extends PagingAndSortingRepository so it already contains functionalities like findAll(Pageable) and save().
In many cases the data grid shows only part of all fields. In this scenario you can add @JsonView(QueryOutput.View.class) to your controller and entity, so only fields marked with @JsonView(QueryOutput.View.class) will be displayed in query output.
@Data
@Document(collection = "order")
public class Order {
@Id
@JsonView(QueryOutput.View.class)
private String id;
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonView(QueryOutput.View.class)
private Date date;
@JsonView(QueryOutput.View.class)
private String orderNumber;
@JsonView(QueryOutput.View.class)
private boolean isValid;
@JsonView(QueryOutput.View.class)
private double price;
/** the detail will not show in query result */
private EmbeddedOrderDetail detail;
}A special designed data grid is designed for this protocol, will be introduced later.
A repository has the following methods:
- Using Query
QueryOutput<T> findAll(QueryInput input);for basic simple query<R> QueryOutput<R> findAll(QueryInput input, Function<T, R> converter);for query with customized data convert
- Using Specification (JPA only)
QueryOutput<T> findAll(QueryInput input, Specification<T> additionalSpecification);QueryOutput<T> findAll(QueryInput input, Specification<T> additionalSpecification, Specification<T> preFilteringSpecification);<R> QueryOutput<R> findAll(QueryInput input, Specification<T> additionalSpecification, Specification<T> preFilteringSpecification, Function<T, R> converter);
- Using Criteria (MongoDB only)
QueryOutput<T> findAll(QueryInput input, Criteria additionalCriteria);QueryOutput<T> findAll(QueryInput input, Criteria additionalCriteria, Criteria preFilteringCriteria);
- Using Aggregation (MongoDB only)
<View> QueryOutput<View> findAll(Class<View> classOfView, QueryInput input, AggregationOperation... operations);<View> QueryOutput<View> findAll(Class<View> classOfView, QueryInput input, Collection<? extends AggregationOperation> operations);
@PostMapping("/data/orders/search")
public QueryOutput<Order> getOrdersByPost(@Valid @RequestBody QueryInput input) {
return repo.findAll(input);
}
@PostMapping("/data/orders/count")
public CountOutput count(@Valid @RequestBody CountInput input) {
return repo.count(input);
}import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
@GetMapping("/")
public QueryOutput<DataView> getAll(@Valid QueryInput input) {
return repo.findAll(DataView.class,
input,
// just provide your aggregation pipeline here
lookup("user", "userId", "id", "user"),
unwind("user"),
project()
.and("user.sex").as("user.gender")
.andInclude(
"timestamp", "createTime", "sensorType",
"batchId", "source", "beginTime",
"endTime", "text", "url", "value")
);
}A more detailed document is here, and with 中文版.
In the near future:
- More complicated tests (and verifications)
$match,$sum: 1,$limitand$skipare attached to given aggregation pipeline so in some cases the logic may be broken.- Text search is simply converted to Regular Expressions with
Literalflag and may contain some logical flaws. - Querydsl support may be missing or error-prone, as my project does not use it.
