使用@Formula计算出生日期的年龄

时间:2017-07-05 17:45:14

标签: java hibernate mariadb

我正在尝试使用@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执行该查询,则可以正常工作。

2 个答案:

答案 0 :(得分:1)

您的第一次尝试几乎是正确的,但您不需要selectfrom部分,因为列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;