转自:http://hellohank.iteye.com/blog/760783 刚好自己在项目中碰到
前段日子在用Hibernate在MySQL数据库中查询数据时,出现了如下MySql语法错误:
- 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>
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:
- hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.dialect=org.hibernate.dialect.MySQLDialect
但为什么使用了正确的Dialect之后,还是会出现上面这个情况呢?
那是因为上面SQL中的INTERVAL是Hibernate语法中的关键词,它不会认为是Mysql中的关键词,于是在解析SQL时就出错了!
那如何才能自定义一个方法,让它支持这样的语法呢?很简单,看一下上面MySQLDialect中的源码,你就会一下子就明白了:我们只需要重新注册一个方法即可!示例代码如下:
- 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)"));
- }
-
- }
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:
- hibernate.dialect=com.cloudframework.dialect.MysqlDialect
hibernate.dialect=com.cloudframework.dialect.MysqlDialect
再然后,将我们上面的SQL改为如下:
- 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了!
分享到:
相关推荐
1. **创建Oracle函数**:在Oracle数据库中,我们首先需要创建一个自定义函数。例如,我们可以创建一个计算两个数字之和的函数`ADD_NUMBERS`: ```sql CREATE OR REPLACE FUNCTION ADD_NUMBERS(p_num1 NUMBER, p_...
在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它简化了数据库操作,使得开发者可以更专注于业务逻辑而不是数据库层面的细节。`BaseDao`是常见的一种设计模式,用于封装Hibernate的基本数据库...
在自定义函数中,我们可以利用Groovy的面向对象特性,定义类和方法来处理明细表和主表的数据交互。 2. **数据访问**:Groovy可以方便地与数据库进行交互,通过JDBC API或者ORM框架(如Hibernate)来查询明细表和主...
通过自定义`Dialect`类,可以实现特定数据库的特性,如存储过程、函数的支持。 3. **元数据动态生成**:在某些情况下,可能需要在运行时根据数据库结构动态生成Java实体类和映射文件。这可以通过解析数据库元数据来...
Hibernate方言(Dialect)是Hibernate框架中的一个关键概念,它是Hibernate与特定数据库之间通信的桥梁。方言定义了如何将Hibernate的SQL语句转换为特定数据库所理解的SQL,包括列类型、约束、SQL语法等。例如,达梦...
2. **自定义数据库操作类**:创建一个包含各种数据库操作方法的类,如`select()`, `insert()`, `update()`, `delete()`等。 3. **使用数据库连接池**:如C3P0、DBCP、HikariCP等,它们管理数据库连接,提供高效的...
在Java开发中,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。而Hibernate Tools是Hibernate项目的一部分,它提供了一系列实用工具,包括代码生成、逆向工程等。本文将深入探讨如何...
在Java Web开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。其中,反向工程(Reverse Engineering)是Hibernate提供的一项功能,它能根据数据库结构自动生成对应的Java实体类、...
### NHibernate HQL 可用函数详解 #### 一、查询基本语法与示例 **1....- **语法**: `FROM <类名> [WHERE <条件>]` - **示例**: `FROM Category c ...通过这些示例,你可以更好地理解和应用HQL来完成数据库操作任务。
10. **事件监听器(Event Listeners)**: Hibernate允许注册监听器来处理对象生命周期中的特定事件,如预加载、加载、保存、更新、删除等,可用于实现自定义业务逻辑。 11. **状态转换(State Transitions)**: ...
2. **实体(Entities)与持久化类**:在Hibernate中,实体代表数据库中的表,而持久化类是与实体对应的Java类。这些类通常包含属性(字段),它们映射到表的列,以及getter和setter方法。 3. **配置文件(Hibernate...
最后,文档可能还涵盖了Hibernate的其他高级特性,如 Criteria API的自定义函数和运算符、查询结果的投影和分组、以及如何自定义类型映射等。 总的来说,《Hibernate3.2中文参考文档》是全面了解和掌握Hibernate...
Hibernate是Java领域中的一款流行的对象关系映射(ORM)工具,它允许开发者使用面向对象的方式处理数据库,简化了数据库与Java对象之间的交互。 1. **Hibernate入门** - **前言**:这部分介绍了Hibernate的基本...
Projections 用于定义查询结果的结构,可以返回单个属性、属性集合或自定义聚合函数的结果。Restrictions 则用于设置查询条件,包括等值比较、范围查询、逻辑运算等多种操作。 ### 6. Native SQL 查询 虽然 HQL 和...
因此,在Hibernate中,如果实体类只定义了带参数的构造函数而没有定义无参构造函数,就可能会出现此错误。 **解决方案**: 1. **添加无参构造函数**:在实体类中显式地添加一个无参构造函数。 ```java public ...
- 解释Hibernate如何支持Java中的继承关系,并映射到数据库表。 - **4.3 实现`equals()`和`hashCode()`** - 讲解为何持久化类应该重写这两个方法,以及如何正确实现它们。 - **4.4 动态模型(Dynamicmodels)** -...
Hibernate是一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序与数据库之间的交互,使得开发人员可以更专注于业务逻辑,而不用过多地处理SQL语句。 在Hibernate3版本中,这个框架已经相当成熟,提供...
在Hibernate应用中,首先需要配置hibernate.cfg.xml文件,定义数据库连接信息、方言、缓存策略等。然后,通过SessionFactory的构建器加载配置,并创建SessionFactory实例,它是线程安全的,整个应用通常只需要一个。...
Hibernate,作为Java领域中的一款著名对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以更加专注于业务逻辑而不是底层的数据存储。本篇将详细解读Hibernate中文API文档,旨在帮助开发者快速理解和...