英文:
Implement search with date range
问题
Here are the translated portions of your content:
要实现使用Spring Boot的日期范围搜索。我尝试了这个:
端点:
@GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public Page<UsersResource> getUsersBySearchSpecification(@Valid UserSearchParams params, Pageable pageable)
{
Page<UsersResource> list = userService.getUsersBySpecification(params, pageable);
return list;
}
UserSearchParams:
@Getter
@Setter
public class UserSearchParams {
private String param1;
private Integer param2;
private List<String> param3;
@DateTimeFormat(iso = DATE_TIME)
LocalDateTime startDate;
private OffsetDateTime createdAt;
}
搜索功能:
public Page<Users> getUsersBySpecification(UserSearchParams params, Pageable pageable)
{
Specification<Users> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getCreatedAt() != null) {
predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
}
if (params.getCreatedAt() != null) {
predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return userRepository.findAll(spec, pageable);
}
这个搜索功能不起作用。createdAt
应该使用什么数据类型?OffsetDateTime
还是 LocalDateTime
更好?
我应该手动解析值 2023-05-02T04:57:19.83795Z
还是可以依赖Spring Boot来解析日期?
这段代码是否正确实现:
if (params.getCreatedAt() != null) {
predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
}
if (params.getCreatedAt() != null) {
predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
}
还有更好的方法来选择日期范围吗?
英文:
I want to implement Date range search using Spring Boot. I tried this:
url: localhost:8080/users/users?page=0&size=3&createdAt=2023-05-02T04:57:19.83795Z
Endpoint:
@GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public Page<UsersResource> getUsersBySearchSpecification(@Valid UserSearchParams params, Pageable pageable)
{
Page<UsersResource> list = userService.getUsersBySpecification(params, pageable);
return list;
}
UserSearchParams:
@Getter
@Setter
public class UserSearchParams {
private String param1;
private Integer param2;
private List<String> param3;
@DateTimeFormat(iso = DATE_TIME)
LocalDateTime startDate;
private OffsetDateTime createdAt;
}
Search functionality:
public Page<Users> getUsersBySpecification(UserSearchParams params, Pageable pageable)
{
Specification<Users> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getCreatedAt() != null) {
predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
}
if (params.getCreatedAt() != null) {
predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return userRepository.findAll(spec, pageable);
}
The search functionality is not working. What data type should I use for createdAt
? OffsetDateTime
or LocalDateTime
is better alternative?
Should I manually parse the value 2023-05-02T04:57:19.83795Z
or I can rely on Spring Boot to parse the date?.
Is this code properly implemented:
if (params.getCreatedAt() != null) {
predicates.add(cb.greaterThan(root.get("createdAt"), params.getCreatedAt()));
}
if (params.getCreatedAt() != null) {
predicates.add(cb.lessThan(root.get("createdAt"), params.getCreatedAt()));
}
Or there is better way to to have this range select?
答案1
得分: 4
Let me answer step by step based on the experience that I have (multiple different enterprise projects). Additional note: I was mostly working with PostgreSQL as a database.
-
通常使用
LocalDateTime
。因为它更方便,没有时区信息。对于数据库,通常使用timestamp
作为适当的列类型。 -
Spring Boot能够解析请求参数到
LocalDateTime
类型,无需显式的自定义配置实现。这是一个LocalDateTime
类型的请求示例:https://localhost:8080/my/endpoint?startDate=2023-01-01T00:30:00.000&endDate=2023-12-31T23:30:00.000
https://localhost:8080/my/endpoint?startDate=2023-01-01T00%3A30%3A00.000&endDate=2023-12-31T23%3A30%3A00.000
(HTML解码)
这是适当的控制器代码:
@GetMapping(value = "/my/endpoint")
public void myMethod(
@RequestParam(name = "startDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime startDate,
@RequestParam(name = "endDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime endDate) {
return doSearch(startDate, endDate);
}
但要小心旧版本的Spring。根据我的经验,从Spring Boot 2.2.X版本开始应该可以工作。***关键是要使用高于2.1版本的JPA实现,因为在2.1版本中使用LocalDateTime
不太方便。***简而言之,请使用现代版本。
更多信息可以在这里找到。
-
至于实现部分。使用
LocalDateTime
和JPA实现2.2或更高版本,你的代码应该可以工作。你也可以在这里检查代码示例:- https://dzone.com/articles/dealing-with-javas-localdatetime-in-jpa
- enter link description here(这是关于
LocalDate
的,但也应该适用于LocalDateTime
)。
英文:
Let me answer step by ste based on the experience that I have (multiple different enterprise projects). Additional note: I was mostly working with PostgreSQL as a database.
-
Usually
LocalDateTime
is used. Because it's a bit more convenient to work with an it has no time-zone info. For databases usuallytimestamp
is the appropriate column type. -
Spring Boot is able to parse request parameters to
LocalDateTime
type without explicit custom config implementations. Here is an example of request forLocalDateTime
type:https://localhost:8080/my/endpoint?startDate=2023-01-01T00:30:00.000&endDate=2023-12-31T23:30:00.000
https://localhost:8080/my/endpoint?startDate=2023-01-01T00%3A30%3A00.000&endDate=2023-12-31T23%3A30%3A00.000
(html decoded)
Here is the appropriate controller code:
@GetMapping(value = "/my/endpoint")
public void myMethod(
@RequestParam(name = "startDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime startDate,
@RequestParam(name = "endDate") @DateTimeFormat(iso = DATE_TIME) LocalDateTime endDate) {
return doSearch(startDate, endDate);
}
But be careful with old Spring versions. From my experience, it should work since Spring Boot 2.2.X. The idea is to have an implementation of JPA higher than 2.1 version, because in 2.1 version there is no convenient using of LocalDateTime
. Simply put, use modern versions.
A bit more information can be found here.
-
As for implementation. Using
LocalDateTime
and JPA implementation 2.2 or higher, your code should work. You can also check code samples here:- https://dzone.com/articles/dealing-with-javas-localdatetime-in-jpa
- enter link description here (it's about
LocalDate
, but should work withLocalDateTime
too.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论