Hibernateでのカスタムデータベース関数
7495 ワード
http://hellohank.iteye.com/blog/760783ちょうど自分がプロジェクトで出会った
先日、MySQLデータベースでHibernateを使用してデータを照会したところ、次のようなMySql構文エラーが発生しました.
Javaコード
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] - 2010-09-11 02:44:23,281 ERROR [org.hibernate.util.JDBCExceptionReporter] -
そこでMysqlの文法を調べてみると、このような書き方は間違いないでしょう.date_add関数はこのように使いますね~ネットで探してみると、本当に多くの人がこの問題に直面していることに気づきました.多くの解決策を提供している人もいます(不思議なことに、これらの解決策は基本的に外国のサイトで提案されているもので、中国語のサイトでは見たことがありませんが、ほほほ)には、カスタム関数の作成、クエリーの変更などのトランスフォームが含まれています.しかし、根本的に問題を解決する方法として、Mysqlで対応する方法をサポートするDialectの方法をカスタマイズする方法もあります.この点は、Hibernからateは各データベースのローカル言語サポートについて述べた.Hibernateでは、ほとんどの主流データベースをサポートし、各データベースと結合するときに、Dialect(データベースローカライズ言語)を使用して、実行されたSQL文を対応するデータベースの実行可能SQLに変換します.(SQLはデータベースによって文法の違いがあるので)Hibernateを使用して異なるデータベースに接続する場合は、対応するDialectを指定する必要があります.私が作ったこのプロジェクトではMysqlを使用しているので、次のDialectも使用しています.
Javaコード
hibernate.dialect=org.hibernate.dialect.MySQLDialect
しかし、なぜ正しいDialectを使った後、このような状況になったのでしょうか.それは上のSQLのINTERVALがHibernate文法のキーワードなので、Mysqlのキーワードとは思えないので、SQLを解析するときにエラーが発生しました!では、このような文法をサポートする方法をカスタマイズするにはどうすればいいのでしょうか.簡単です.上のMySQLDialectのソースコードを見てみると、私たちは方法を再登録するだけでいいことがわかります.サンプルコードは次のとおりです.
Javaコード
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_MySQLのdate_をサポートするためのIntervalメソッドadd関数のINTERVAL.次に、このカスタムDialectを使用します.
Javaコード
hibernate.dialect=com.cloudframework.dialect.MysqlDialect
次に、上のSQLを次のように変更します.
Javaコード
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!
先日、MySQLデータベースでHibernateを使用してデータを照会したところ、次のようなMySql構文エラーが発生しました.
Javaコード
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関数はこのように使いますね~ネットで探してみると、本当に多くの人がこの問題に直面していることに気づきました.多くの解決策を提供している人もいます(不思議なことに、これらの解決策は基本的に外国のサイトで提案されているもので、中国語のサイトでは見たことがありませんが、ほほほ)には、カスタム関数の作成、クエリーの変更などのトランスフォームが含まれています.しかし、根本的に問題を解決する方法として、Mysqlで対応する方法をサポートするDialectの方法をカスタマイズする方法もあります.この点は、Hibernからateは各データベースのローカル言語サポートについて述べた.Hibernateでは、ほとんどの主流データベースをサポートし、各データベースと結合するときに、Dialect(データベースローカライズ言語)を使用して、実行されたSQL文を対応するデータベースの実行可能SQLに変換します.(SQLはデータベースによって文法の違いがあるので)Hibernateを使用して異なるデータベースに接続する場合は、対応するDialectを指定する必要があります.私が作ったこのプロジェクトではMysqlを使用しているので、次のDialectも使用しています.
Javaコード
hibernate.dialect=org.hibernate.dialect.MySQLDialect
しかし、なぜ正しいDialectを使った後、このような状況になったのでしょうか.それは上のSQLのINTERVALがHibernate文法のキーワードなので、Mysqlのキーワードとは思えないので、SQLを解析するときにエラーが発生しました!では、このような文法をサポートする方法をカスタマイズするにはどうすればいいのでしょうか.簡単です.上のMySQLDialectのソースコードを見てみると、私たちは方法を再登録するだけでいいことがわかります.サンプルコードは次のとおりです.
Javaコード
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_MySQLのdate_をサポートするためのIntervalメソッドadd関数のINTERVAL.次に、このカスタムDialectを使用します.
Javaコード
hibernate.dialect=com.cloudframework.dialect.MysqlDialect
次に、上のSQLを次のように変更します.
Javaコード
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!