JPA:如何通过字符串 UUID select 二进制(16)UUID?
JPA: How to select a binary(16) UUID by a String UUID?
我有以下实体:
@Data
@Entity
public class Comment implements Serializable {
@Id
@GeneratedValue(generator = "uuid4")
@GenericGenerator(name = "UUID", strategy = "uuid4")
@Column(columnDefinition = "BINARY(16)")
private UUID id;
@Column(columnDefinition = "BINARY(16)")
private UUID imageId;
private Instant creationTime;
private String text;
}
还有一个 CRUD 回购:
public interface CommentsRepository extends CrudRepository<Comment, UUID> {
List<Comment> findAllByImageId(final UUID imageId);
}
我添加了一些示例数据:
@Component
@Slf4j
public class CommentsSampleData implements CommandLineRunner {
private final CommentsRepository repository;
@Autowired
public CommentsSampleData(final CommentsRepository repository) {
this.repository = repository;
}
@Override
public void run(String... args) {
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment1");
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment2");
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment3");
createComment("e3a8aa57-6937-4f9e-b117-78bafe61b718", Instant.now(), "comment1");
}
private void createComment(
final String imageId,
final Instant creationTime,
final String text) {
final Comment comment = new Comment();
comment.setImageId(UUID.fromString(imageId));
comment.setCreationTime(creationTime);
comment.setText(text);
log.info("save comment: {}", comment);
repository.save(comment);
}
}
所以我的 table 中的数据如下所示:
那么现在通过那些二进制 UUID select 的最佳方法是什么?
我将从前端获取字符串 UUID,所以我想我需要以某种方式将这些字符串转换为二进制文件。最好的方法是什么,以便它也适用于 ID 和主键。
示例端点:
@Slf4j
@RestController
public class CommentsController {
private final CommentsService service;
public CommentsController(final CommentsService service) {
this.service = service;
}
@GetMapping(value = "/comments", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Comment> getComments(@RequestParam("imageId") final UUID imageId) {
log.info("get comments by imageId: {}", imageId);
String existingIds = service.findAll().stream()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Image Id Passed: {}", imageId);
log.info("Existing image ids: {}", existingIds);
String resultIds = service.findAllByImageId(imageId).stream()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Result image ids: {}", resultIds);
return service.findAllByImageId(imageId);
}
}
当我现在做一个请求时:
localhost:8080/comments?imageId=617220ff-1642-4490-b589-869e7978c5e0
即使 UUID 存在但不是字符串形式,我也没有得到任何结果,它在数据库中以二进制 (16) 形式存在:
d.f.a.c.service.CommentsController : Image Id Passed: 617220ff-1642-4490-b589-869e7978c5e0
d.f.a.c.service.CommentsController : Existing image ids: 617220ff-1642-4490-b589-869e7978c5e0,617220ff-1642-4490-b589-869e7978c5e0,617220ff-1642-4490-b589-869e7978c5e0,e3a8aa57-6937-4f9e-b117-78bafe61b718
d.f.a.c.service.CommentsController : Result image ids:
它按预期工作,没有任何问题,并且在 UUID 和二进制之间自动转换。
我建议尝试以下操作以确保该 ID 确实存在于数据库中。
@GetMapping(value = "/comments", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<Comment> getComments(@RequestParam("imageId")
final UUID imageId) {
log.info("get comments by imageId: {}", imageId);
String existingIds = service.findAll()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Image Id Passed : {}", imageId);
log.info("Existing image ids : {}", existingIds);
return service.findAllByImageId(imageId);
}
我有以下实体:
@Data
@Entity
public class Comment implements Serializable {
@Id
@GeneratedValue(generator = "uuid4")
@GenericGenerator(name = "UUID", strategy = "uuid4")
@Column(columnDefinition = "BINARY(16)")
private UUID id;
@Column(columnDefinition = "BINARY(16)")
private UUID imageId;
private Instant creationTime;
private String text;
}
还有一个 CRUD 回购:
public interface CommentsRepository extends CrudRepository<Comment, UUID> {
List<Comment> findAllByImageId(final UUID imageId);
}
我添加了一些示例数据:
@Component
@Slf4j
public class CommentsSampleData implements CommandLineRunner {
private final CommentsRepository repository;
@Autowired
public CommentsSampleData(final CommentsRepository repository) {
this.repository = repository;
}
@Override
public void run(String... args) {
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment1");
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment2");
createComment("617220ff-1642-4490-b589-869e7978c5e0", Instant.now(), "comment3");
createComment("e3a8aa57-6937-4f9e-b117-78bafe61b718", Instant.now(), "comment1");
}
private void createComment(
final String imageId,
final Instant creationTime,
final String text) {
final Comment comment = new Comment();
comment.setImageId(UUID.fromString(imageId));
comment.setCreationTime(creationTime);
comment.setText(text);
log.info("save comment: {}", comment);
repository.save(comment);
}
}
所以我的 table 中的数据如下所示:
那么现在通过那些二进制 UUID select 的最佳方法是什么? 我将从前端获取字符串 UUID,所以我想我需要以某种方式将这些字符串转换为二进制文件。最好的方法是什么,以便它也适用于 ID 和主键。
示例端点:
@Slf4j
@RestController
public class CommentsController {
private final CommentsService service;
public CommentsController(final CommentsService service) {
this.service = service;
}
@GetMapping(value = "/comments", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Comment> getComments(@RequestParam("imageId") final UUID imageId) {
log.info("get comments by imageId: {}", imageId);
String existingIds = service.findAll().stream()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Image Id Passed: {}", imageId);
log.info("Existing image ids: {}", existingIds);
String resultIds = service.findAllByImageId(imageId).stream()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Result image ids: {}", resultIds);
return service.findAllByImageId(imageId);
}
}
当我现在做一个请求时:
localhost:8080/comments?imageId=617220ff-1642-4490-b589-869e7978c5e0
即使 UUID 存在但不是字符串形式,我也没有得到任何结果,它在数据库中以二进制 (16) 形式存在:
d.f.a.c.service.CommentsController : Image Id Passed: 617220ff-1642-4490-b589-869e7978c5e0
d.f.a.c.service.CommentsController : Existing image ids: 617220ff-1642-4490-b589-869e7978c5e0,617220ff-1642-4490-b589-869e7978c5e0,617220ff-1642-4490-b589-869e7978c5e0,e3a8aa57-6937-4f9e-b117-78bafe61b718
d.f.a.c.service.CommentsController : Result image ids:
它按预期工作,没有任何问题,并且在 UUID 和二进制之间自动转换。
我建议尝试以下操作以确保该 ID 确实存在于数据库中。
@GetMapping(value = "/comments", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<Comment> getComments(@RequestParam("imageId")
final UUID imageId) {
log.info("get comments by imageId: {}", imageId);
String existingIds = service.findAll()
.map(Comment::getImageId)
.map(UUID::toString)
.collect(Collectors.joining(","));
log.info("Image Id Passed : {}", imageId);
log.info("Existing image ids : {}", existingIds);
return service.findAllByImageId(imageId);
}