-
Notifications
You must be signed in to change notification settings - Fork 26
Unified Criteria API support
This document describes the support for the Unified Criteria API in doma-spring-boot, which provides seamless integration between Spring Data's Pageable interface and Doma's Criteria API.
The Unified Criteria API support bridges the gap between Spring Data pagination (Pageable) and Doma's Criteria API, allowing you to:
- Convert
Pageablepagination parameters into Doma'slimit()andoffset()methods - Transform Spring Data's
Sortinformation into Doma'sorderBy()clauses - Handle property name mapping between Spring Data and Doma entity metamodels
The UnifiedCriteriaPageable class is the main adapter that converts Pageable objects into Doma Criteria API specifications.
-
offset()- ConvertsPageablepage information to offset value -
limit()- ConvertsPageablepage size to limit value -
orderBy()- Creates ordering consumer based on sort specifications
A functional interface that maps property names to Doma's PropertyMetamodel instances:
@FunctionalInterface
public interface PropertyMetamodelResolver {
Optional<PropertyMetamodel<?>> resolve(String propertyName);
}The Unified Criteria API support is automatically configured when the following classes are present on the classpath:
org.seasar.doma.jdbc.criteria.Entityqlorg.seasar.doma.jdbc.criteria.NativeSql
The auto-configuration provides:
@Bean
@ConditionalOnMissingBean(Entityql.class)
public Entityql entityql(Config config) {
return new Entityql(config);
}
@Bean
@ConditionalOnMissingBean(NativeSql.class)
public NativeSql nativeSql(Config config) {
return new NativeSql(config);
}The simplest way to use UnifiedCriteriaPageable is with an entity metamodel:
@RestController
public class MessageController {
private final QueryDsl queryDsl;
@GetMapping("/messages")
public List<Message> list(@PageableDefault(size = 10, sort = "id,asc") Pageable pageable) {
var message = new Message_(); // Entity metamodel
var p = UnifiedCriteriaPageable.from(pageable, message);
return queryDsl.from(message)
.offset(p.offset())
.limit(p.limit())
.orderBy(p.orderBy())
.fetch();
}
}For more control over property name resolution:
@GetMapping("/messages")
public List<Message> list(Pageable pageable) {
var message = new Message_();
var p = UnifiedCriteriaPageable.of(pageable, propertyName -> {
return switch (propertyName) {
case "messageText" -> Optional.of(message.text);
case "messageId" -> Optional.of(message.id);
default -> Optional.empty();
};
});
return queryDsl.from(message)
.offset(p.offset())
.limit(p.limit())
.orderBy(p.orderBy())
.fetch();
}Specify a default ordering when no sort is provided:
@GetMapping("/messages")
public List<Message> list(Pageable pageable) {
var message = new Message_();
var p = UnifiedCriteriaPageable.from(pageable, message,
orderBy -> orderBy.desc(message.id)); // Default ordering
return queryDsl.from(message)
.offset(p.offset())
.limit(p.limit())
.orderBy(p.orderBy())
.fetch();
}Handle cases where sort properties don't exist in the entity:
@GetMapping("/messages")
public List<Message> list(Pageable pageable) {
var message = new Message_();
var p = UnifiedCriteriaPageable.from(pageable, message);
return queryDsl.from(message)
.offset(p.offset())
.limit(p.limit())
.orderBy(p.orderBy(missingProperties -> {
if (!missingProperties.isEmpty()) {
throw new IllegalArgumentException(
"Invalid sort properties: " + String.join(", ", missingProperties)
);
}
}))
.fetch();
}For full pagination support with total count:
@GetMapping("/messages")
public Page<Message> getPage(Pageable pageable) {
var message = new Message_();
var p = UnifiedCriteriaPageable.from(pageable, message);
// Get paginated content
var content = queryDsl.from(message)
.offset(p.offset())
.limit(p.limit())
.orderBy(p.orderBy())
.fetch();
// Get total count
var total = queryDsl.from(message)
.select(Expressions.count())
.fetchOne();
return new PageImpl<>(content, pageable, total);
}For advanced configurations, use SortConfig:
var sortConfig = new UnifiedCriteriaPageable.SortConfig(
propertyName -> { /* custom property resolution */ },
orderBy -> { /* default ordering */ }
);
var p = UnifiedCriteriaPageable.of(pageable, sortConfig);