-
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
Pageable
pagination parameters into Doma'slimit()
andoffset()
methods - Transform Spring Data's
Sort
information 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()
- ConvertsPageable
page information to offset value -
limit()
- ConvertsPageable
page 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.Entityql
org.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);