我需要在MySQL中保留一系列任务。从DB读取它时,我必须确保订单与它们保持完全相同。 一般来说,我更喜欢使用解决方案DB不可知(即纯JPA),但也可以添加一些Hibernate和/或MySQL。
我的(可能是天真的)第一个版本看起来像:
em.createNamedQuery("MyQuery", MyTask.class).setFirstResult(0).setMaxResults(count).getResultList();
MyQuery
没有任何“order by”子句,即它看起来像:
SELECT t FROM MyTasks
这种方法是否可以保证传入的结果/实体按照它们的持久方式进行排序?如果我也启用了缓存怎么办?
我还在考虑向任务实体添加一个额外的字段,这是一个以毫秒(UTC from 1970-01-01)
为单位的时间戳,然后在查询中按顺序排序,但后来我可能处于两个任务立即生成的情况中在另一个之后,他们有相同的时间戳。
欢迎任何解决方案/想法!
编辑: 我刚刚意识到自动增量(至少在MySQL中)一旦达到其最大值就会抛出异常,并且不会有更多的插入。这意味着我不应该担心数据库重置计数器,我可以通过查询中的“自动增量”列明确排序。当然我还有另外一个问题需要处理,即如果卷太高以至于MySQL中最大可能的无符号整数类型不够大但该问题与我现在正在处理的问题无关。
答案 0 :(得分:1)
关注纯JPA解决方案,导致实体MyTasks must have a primary key我建议您使用Sequence Generator作为其主键,并使用键上的order by子句对查询结果进行排序。
例如:
@Entity
class MyTask {
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE)
private Long id;
您还可以使用@SequenceGenerator将数据库与数据库紧密一致,以指定数据库中定义的生成器。
编辑:您是否看过@PrePersist选项来设置时间戳?也许你可以按顺序组合时间戳字段和id顺序生成和顺序,因此时间戳冲突由id比较(它是唯一的)来解决。
答案 1 :(得分:0)
大多数RDBMS将按插入顺序存储,并且没有其他指令也会以这种方式对结果进行排序。如果你不想让它失去理智,你有几个选择。
1)您可以使用时间戳和递增的固定长度数字生成合理唯一的ID,
OR
2)您可以使用自动编号的主键定义表(这可能更容易)。
如果表中有一个主键可以按顺序排序,那么默认情况下,大多数RDBMS将按升序主键顺序返回...或者您可以在查询中明确强制执行。