我正在开发一个应用程序,其中有用户具有常规字段,如用户 ID、姓名等,此外用户还有分数和排名。排名是根据请求计算的,具体取决于用户的分数。它实际上是用户在整个系统中的顺序,得分最高的用户的排名为1。
我使用 hibernate 4 作为 orm,使用 mysql 5.1... 作为 db ; 我的 User 类如下,正如我之前所说,排名不是数据库中的列;
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(insertable = false, updatable = false)
Integer userId;
@Column
String name;
@Column
Integer score;
Integer rank; // rank is calculated according to score
...
这里是检索用户订单的sql语句;
SELECT COUNT( score ) + 1 as rank
FROM users
WHERE users.score > ( SELECT users.score
FROM users WHERE `users`.`userId` = :uid)
我还可以使用存储的数据库函数或过程。
是否可以像嵌套一样在每个请求上检索用户的排名以及用户实体的其他属性?
使用注释的解决方案非常受欢迎。
最佳答案
我相信您想要的是研究 @Formula
注释。它只是将您放入其中的任何代码片段作为该列的 select 子句的一部分放入其中,并使该属性成为只读。 (@ColumnTransformer
是相同的想法,只是它支持双向函数。)
像下面这样的东西应该可以工作:
@Formula("(SELECT COUNT( score ) + 1 FROM users u WHERE u.score > ( SELECT score FROM users u2 WHERE u2.userId = id))")
Integer rank;
注意:id不合格,hibernate将为User类的表生成别名前缀。
这并不是 Hibernate 的一个特别详细记录的功能。但请参阅:http://docs.jboss.org/hibernate/core/4.3/manual/en-US/html/ch05.html#mapping-declaration-property - 5.1.4.1.5。公式。
您可以查看http://www.jroller.com/eyallupu/entry/hibernate_derived_properties_performance_and 。
你也可以用正常的方式让它变得懒惰。
替代方案
您还可以创建一个嵌入此 sql 的用户 View 。这在某些情况下可能很有值(value),但会使您的实体只读。 (有些数据库确实支持针对 View 的 DML,但我不能说在这种情况下它的效果如何,并且您要求基于 Hibernate 的解决方案。)
关于java - 如何在 Hibernate 4 上获取来自 select 语句的实体的一个字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22443153/