我正在尝试使用@Formula
从出生日期开始计算用户的年龄。
根据MySQL documentation,我试过了这个:
@Entity
@Table(name = "users")
public final class UserProfile {
//this column is called BIRTHDATE in database
private String birthdate;
@Formula("(select TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()) from users)")
private String age;
//more things...
}
但是我收到了一个错误:
java.sql.SQLSyntaxErrorException:您的SQL中有错误 句法;检查与MariaDB服务器对应的手册 正确使用near语法的版本 'userprofil0_.YEAR,userprofil0_.BIRTHDATE,CURDATE())来自用户)as 第0行的formula0_0_ f'
如果我在phpMyAdmin中执行该查询,它可以正常工作。
关注this,我也尝试过:
@Formula("date_part('year', age(birthdate))")
private String age; //I tried with int instead of String, too
但我有这个错误:
java.sql.SQLSyntaxErrorException:FUNCTION userprofile-service-db.date_part不存在
这个甚至在phpMyAdmin中都不起作用......
有什么想法吗?
修改
我刚试过:
@Formula("(TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()))")
private String age;
但仍然无法正常工作。这是Hibernate显示的查询:
select
userprofil0_.id as id1_1_0_,
userprofil0_.about_me as about_me2_1_0_,
userprofil0_.birthdate as birthdat3_1_0_,
userprofil0_.display_name as display_4_1_0_,
userprofil0_.email as email5_1_0_,
userprofil0_.profile_photo as profile_6_1_0_,
(TIMESTAMPDIFF(userprofil0_.YEAR,
userprofil0_.BIRTHDATE,
CURDATE())) as formula0_0_
from
users userprofil0_
where
userprofil0_.id=?
看起来Hibernate将YEAR
作为一列,但实际上它是一个保留字。如果我在phpMyAdmin中用userprofil0_.YEAR
替换YEAR
执行该查询,则可以正常工作。
答案 0 :(得分:1)
您的第一次尝试几乎是正确的,但您不需要select
和from
部分,因为列BITHDATE
位于同一个表中:
@Formula("(TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()))")
private String age;
打开生成的SQL查询的日志记录(在Hibernate中通过将属性show_sql
设置为true
来完成)也是有用的,以查看整个查询。
<强>更新强>
作为Hibernate将YEAR
作为列名称处理的解决方法,您可以在自定义MySQL函数中包含对TIMESTAMPDIFF
的调用,并在Formula中调用此函数。以下是针对类似问题的SO answer。
另一种解决方案是编写自定义方言解析器,将YEAR视为关键字:SO answer
答案 1 :(得分:0)
尝试使用此公式来计算当前日期与数据库中存储的BIRTHDATE列之间的差额,以获取用户年龄(年)
@Formula("YEAR(CURDATE()) - YEAR(BIRTHDATE)")
private int age;