`

Hibernate中自定义数据库函数

 
阅读更多

转自:http://hellohank.iteye.com/blog/760783  刚好自己在项目中碰到

 

前段日子在用Hibernate在MySQL数据库中查询数据时,出现了如下MySql语法错误:

Java代码 复制代码 收藏代码
  1. Hibernate: select count(*) as col_0_0_ from customer customer0_ where 1=1 and (customer0_.primary_customer_id is null) and (birthday between date_add(curdate(), INTERVAL -22, DAY) and curdate())   
  2. 2010-09-11 02:44:23,281 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 1064, SQLState: 42000>   
  3. 2010-09-11 02:44:23,281 ERROR [org.hibernate.util.JDBCExceptionReporter] - <You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' DAY) and curdate())' at line 1>  
Hibernate: select count(*) as col_0_0_ from customer customer0_ where 1=1 and (customer0_.primary_customer_id is null) and (birthday between date_add(curdate(), INTERVAL -22, DAY) and curdate())
2010-09-11 02:44:23,281 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 1064, SQLState: 42000>
2010-09-11 02:44:23,281 ERROR [org.hibernate.util.JDBCExceptionReporter] - <You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' DAY) and curdate())' at line 1>


于是查阅Mysql语法,发现这样的写法没错啊,date_add函数是这样使用呀~

在网上找了一下,发现还真有不少人遇到这个问题,也有人提供了许多解决办法(奇怪的是这些解决办法基本上是人家外国网站上有人提出的,中文网站上我没见到过,呵呵),其中包括:创建自定义函数、改变查询方式等变通方式。

但也有一个从根本上解决问题的方式:自定义Dialect中的方法,使其支持Mysql中对应的方法。这一点,得从Hibernate对各数据库的本地语言支持说起了。

在Hibernate中,它可以支持大多数主流数据库,在与各数据库结合时,它通过Dialect(即数据库本地化语言)将执行的SQL语句转换为对应数据库中的可执行SQL(因为不同数据库中,SQL会存在一些语法的不一样),所以使用Hibernate与不同的数据库连接时,需要指定对应的Dialect。在我做的这个项目中,使用的是Mysql,因此,也就使用了下面的Dialect:

Java代码 复制代码 收藏代码
  1. hibernate.dialect=org.hibernate.dialect.MySQLDialect  
hibernate.dialect=org.hibernate.dialect.MySQLDialect


但为什么使用了正确的Dialect之后,还是会出现上面这个情况呢?
那是因为上面SQL中的INTERVAL是Hibernate语法中的关键词,它不会认为是Mysql中的关键词,于是在解析SQL时就出错了!
那如何才能自定义一个方法,让它支持这样的语法呢?很简单,看一下上面MySQLDialect中的源码,你就会一下子就明白了:我们只需要重新注册一个方法即可!示例代码如下:

Java代码 复制代码 收藏代码
  1. package com.cloudframework.dialect;   
  2.   
  3. import org.hibernate.Hibernate;   
  4. import org.hibernate.dialect.MySQLDialect;   
  5. import org.hibernate.dialect.function.SQLFunctionTemplate;   
  6.   
  7. public class MysqlDialect extends MySQLDialect {   
  8.   
  9.     public MysqlDialect() {   
  10.         super();   
  11.         registerFunction("date_add_interval"new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));   
  12.     }   
  13.   
  14. }  
package com.cloudframework.dialect;

import org.hibernate.Hibernate;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;

public class MysqlDialect extends MySQLDialect {

	public MysqlDialect() {
		super();
		registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
	}

}


在上面的代码中,我们定义了一个date_add_interval方法,目的是使它支持MySQL中的date_add函数中的INTERVAL。
然后我们使用这个自定义的Dialect:

Java代码 复制代码 收藏代码
  1. hibernate.dialect=com.cloudframework.dialect.MysqlDialect  
hibernate.dialect=com.cloudframework.dialect.MysqlDialect


再然后,将我们上面的SQL改为如下:

Java代码 复制代码 收藏代码
  1. select count(*) as col_0_0_ from customer customer0_ where 1=1 and (customer0_.primary_customer_id is null) and (birthday between date_add_interval(curdate(), -22, DAY) and curdate())  
select count(*) as col_0_0_ from customer customer0_ where 1=1 and (customer0_.primary_customer_id is null) and (birthday between date_add_interval(curdate(), -22, DAY) and curdate())


然后再执行,就OK了!

分享到:
评论

相关推荐

    hibernate 调用oracle函数

    1. **创建Oracle函数**:在Oracle数据库中,我们首先需要创建一个自定义函数。例如,我们可以创建一个计算两个数字之和的函数`ADD_NUMBERS`: ```sql CREATE OR REPLACE FUNCTION ADD_NUMBERS(p_num1 NUMBER, p_...

    Hibernate底层数据库操作函数BaseDao+具体实例

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它简化了数据库操作,使得开发者可以更专注于业务逻辑而不是数据库层面的细节。`BaseDao`是常见的一种设计模式,用于封装Hibernate的基本数据库...

    通过groovy自定义函数实现提取明细表字段至主表字段.rar

    在自定义函数中,我们可以利用Groovy的面向对象特性,定义类和方法来处理明细表和主表的数据交互。 2. **数据访问**:Groovy可以方便地与数据库进行交互,通过JDBC API或者ORM框架(如Hibernate)来查询明细表和主...

    hibernate动态数据库进化版

    通过自定义`Dialect`类,可以实现特定数据库的特性,如存储过程、函数的支持。 3. **元数据动态生成**:在某些情况下,可能需要在运行时根据数据库结构动态生成Java实体类和映射文件。这可以通过解析数据库元数据来...

    达梦Hibernate方言2.0至4.0

    Hibernate方言(Dialect)是Hibernate框架中的一个关键概念,它是Hibernate与特定数据库之间通信的桥梁。方言定义了如何将Hibernate的SQL语句转换为特定数据库所理解的SQL,包括列类型、约束、SQL语法等。例如,达梦...

    封装后的数据库操作函数

    2. **自定义数据库操作类**:创建一个包含各种数据库操作方法的类,如`select()`, `insert()`, `update()`, `delete()`等。 3. **使用数据库连接池**:如C3P0、DBCP、HikariCP等,它们管理数据库连接,提供高效的...

    自定义 Hibernate Tools 的模板

    在Java开发中,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而Hibernate Tools是Hibernate项目的一部分,它提供了一系列实用工具,包括代码生成、逆向工程等。本文将深入探讨如何...

    hibernate反向工程模板(已修改)

    在Java Web开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。其中,反向工程(Reverse Engineering)是Hibernate提供的一项功能,它能根据数据库结构自动生成对应的Java实体类、...

    NHibernate hql 可用函数,函数大全

    ### NHibernate HQL 可用函数详解 #### 一、查询基本语法与示例 **1....- **语法**: `FROM &lt;类名&gt; [WHERE &lt;条件&gt;]` - **示例**: `FROM Category c ...通过这些示例,你可以更好地理解和应用HQL来完成数据库操作任务。

    hibernate3 中文API

    10. **事件监听器(Event Listeners)**: Hibernate允许注册监听器来处理对象生命周期中的特定事件,如预加载、加载、保存、更新、删除等,可用于实现自定义业务逻辑。 11. **状态转换(State Transitions)**: ...

    Hibernate v3.04中文参考手册(PDF)

    2. **实体(Entities)与持久化类**:在Hibernate中,实体代表数据库中的表,而持久化类是与实体对应的Java类。这些类通常包含属性(字段),它们映射到表的列,以及getter和setter方法。 3. **配置文件(Hibernate...

    Hibernate3.2中文参考文档

    最后,文档可能还涵盖了Hibernate的其他高级特性,如 Criteria API的自定义函数和运算符、查询结果的投影和分组、以及如何自定义类型映射等。 总的来说,《Hibernate3.2中文参考文档》是全面了解和掌握Hibernate...

    HIBERNATE - 符合Java习惯的关系数据库持久化.docx

    Hibernate是Java领域中的一款流行的对象关系映射(ORM)工具,它允许开发者使用面向对象的方式处理数据库,简化了数据库与Java对象之间的交互。 1. **Hibernate入门** - **前言**:这部分介绍了Hibernate的基本...

    Hibernate3.2中文文档

    Projections 用于定义查询结果的结构,可以返回单个属性、属性集合或自定义聚合函数的结果。Restrictions 则用于设置查询条件,包括等值比较、范围查询、逻辑运算等多种操作。 ### 6. Native SQL 查询 虽然 HQL 和...

    Hibernate错误及解决办法集合

    因此,在Hibernate中,如果实体类只定义了带参数的构造函数而没有定义无参构造函数,就可能会出现此错误。 **解决方案**: 1. **添加无参构造函数**:在实体类中显式地添加一个无参构造函数。 ```java public ...

    hibernate 3.2中文手册 中文文档

    - 解释Hibernate如何支持Java中的继承关系,并映射到数据库表。 - **4.3 实现`equals()`和`hashCode()`** - 讲解为何持久化类应该重写这两个方法,以及如何正确实现它们。 - **4.4 动态模型(Dynamicmodels)** -...

    hibernate3 chm 格式 中文

    Hibernate是一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序与数据库之间的交互,使得开发人员可以更专注于业务逻辑,而不用过多地处理SQL语句。 在Hibernate3版本中,这个框架已经相当成熟,提供...

    Hibernate3.6中文API帮助文档

    在Hibernate应用中,首先需要配置hibernate.cfg.xml文件,定义数据库连接信息、方言、缓存策略等。然后,通过SessionFactory的构建器加载配置,并创建SessionFactory实例,它是线程安全的,整个应用通常只需要一个。...

    Hibernate 中文api文档下载.zip_API_Hibernate API _hibernate api

    Hibernate,作为Java领域中的一款著名对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以更加专注于业务逻辑而不是底层的数据存储。本篇将详细解读Hibernate中文API文档,旨在帮助开发者快速理解和...

Global site tag (gtag.js) - Google Analytics