引言:为什么这样的需求,源自公司项目需要,公司的项目使用java的struts2+spring2.5+oracle中间件tuxedo,数据库用的是Oracle,但由于不直接连接数据库,用中间件处理的方式,又不希望有太多服务,所以就开始网络找资料整理编码了。大概花了一个多星期完成了这个任务,现在整理出来与大家分享,也是自己知识的梳理。

  1.需要导入相关的jar: [按字母顺序排列]

antlr-2.7.5H3.jar           语言转换工,Hibernate利用它实现 HQL 到 SQL的转换

asm.jar               ASM 字节转换库

cglib-2.1.2.jar             高效的代码生成工具, Hibernate用它在运行时扩展 Java类和实现 Java 接口

classes12.jar              Oracle数据库驱动

commons-collections-2.1.1.jar      Apache 的工具集,用来增强Java对集合的处理能力

commons-logging-1.0.4.jar        Apache 软件基金组所提供的日志工具

dom4j-1.6.1.jar               dom4j XML 解析器

hibernate.jar                  Hibernate的核心库

jta.jar                      标准的 JAVA 事务处理接口

2. 在项目src 下加入 hibernate.cfg.xml ,并配置

 配置数据库方言dialect,和实体映射文件mapping,其他属性可以不用配置,因为不需要用到,注意:数据库连接url 不要加,因为加了后,程序会试图去连接。

 1 <?xml version='1.0' encoding='UTF-8'?>
2 <!DOCTYPE hibernate-configuration PUBLIC
3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
5
6 <!-- Generated by MyEclipse Hibernate Tools. -->
7 <hibernate-configuration>
8 <session-factory>
9 <!-- 因为项目只需用Hibernate把hql转换成sql,包括无参数,有参数及需要格式化的参数
10 <property name="connection.url">
11 jdbc:oracle:thin:@127.0.0.1:1521:javacrm
12 </property>
13 <property name="connection.username">scott</property>
14 <property name="connection.password">tiger</property>
15 <property name="connection.driver_class">
16 oracle.jdbc.driver.OracleDriver
17 </property>
18 <property name="show_sql">true</property>
19 <property name="format_sql">true</property>
20 -->
21 <!-- 数据库方言 -->
22 <property name="dialect">
23 org.hibernate.dialect.Oracle10gDialect
24 </property>
25 <!-- 实体映射文件 -->
26 <mapping resource="com/test/bean/Student.hbm.xml"/>
27 <mapping resource="com/test/bean/BasDicConstant.hbm.xml"/>
28
29 </session-factory>
30 </hibernate-configuration>

3. 编写获取Session公共类 DbUtil.java

 

4. 编写核心转换类 HqlToSql.java

  1 package com.test.hqlc;
2
3 import java.util.Collections;
4 import java.util.List;
5
6 import org.hibernate.Session;
7 import org.hibernate.hql.ast.QueryTranslatorImpl;
8 import org.hibernate.impl.SessionFactoryImpl;
9
10 import com.test.util.DbUtil;
11
12 /**
13 * 传入hql语句,参数值列表,返回可执行的sql语句
14 * @author xiufen.huang by 2014-07-03
15 */
16 public class HqlToSql {
17
18 /**
19 * 处理结果信息,成功:为空,失败:错误信息
20 */
21 private static String resultMsg = "" ;
22 private static final String nullMsg = "传入的hql为null或空!";
23
24 /**
25 * 获取处理结果信息,成功:为空,失败:错误信息
26 * @return 处理结果信息
27 */
28 public static String getResultMsg() {
29 return resultMsg;
30 }
31
32 /**
33 * 将hql语句转换为sql语句,无参数
34 * @param hql 要转换的hql语句
35 * @return 可执行的sql语句,当返回null,可以通过getResultMsg()方法查看处理结果信息
36 */
37 public static String transHqlToSql(String hql){
38 // 当hql为null或空时,直接返回null
39 if (hql == null || hql.equals("")) {
40 resultMsg = nullMsg;
41 return null;
42 }
43 // 获取当前session
44 Session session = DbUtil.currentSession();
45 // 得到session工厂实现类
46 SessionFactoryImpl sfi = (SessionFactoryImpl)session.getSessionFactory();
47 // 得到Query转换器实现类
48 QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(hql, hql, Collections.EMPTY_MAP, sfi);
49 queryTranslator.compile(Collections.EMPTY_MAP, false);
50 // 得到sql
51 String sql = queryTranslator.getSQLString();
52 // 关闭session
53 DbUtil.closeSession();
54 return sql;
55 }
56
57 /**
58 * 将hql语句转换为sql语句,不需要格式化参数的情况
59 * @param hql 要转换的hql语句
60 * @param paramValues hql参数值列表,注意与参数的顺序一致
61 * @return 可执行的sql语句,当返回null,可以通过getResultMsg()方法查看处理结果信息
62 */
63 public static String transHqlToSql(String hql,List paramValues){
64 // 要返回的sql语句
65 String sql = transHqlToSql(hql);
66 // 当为null或空时,返回null
67 if (sql == null || sql.equals("")) {
68 resultMsg = nullMsg;
69 return null;
70 }
71
72 // 赋参数值
73 if (paramValues != null && paramValues.size() > 0) {
74 for (int i = 0; i < paramValues.size(); i++) {
75 sql = sql.replaceFirst("\\?", "\\'"+paramValues.get(i).toString()+"\\'");
76 }
77 }
78 return sql;
79 }
80
81 /**
82 * 将hql语句转换为sql语句,有日期,Char等需要格式化参数的情况
83 * @param hql 要转换的hql语句
84 * @param paramValues hql参数值列表,注意与参数的顺序一致
85 * @return 可执行的sql语句,当返回null,可以通过getResultMsg()方法查看处理结果信息
86 */
87 public static String formatHqlToSql(String hql,List<TransTemp> paramValues){
88 // 要返回的sql语句
89 String sql = transHqlToSql(hql);
90 // 当为null或空时,返回null
91 if (sql == null || sql.equals("")) {
92 resultMsg = nullMsg;
93 return null;
94 }
95
96 // 赋参数值
97 if (paramValues != null && paramValues.size() > 0) {
98 for (int i = 0; i < paramValues.size(); i++) {
99 TransTemp tt = paramValues.get(i);
100 sql = sql.replaceFirst("\\?", tt.getOracleFormatString());
101 }
102 }
103 return sql;
104 }
105
106 }

5.测试实例 HqlToSqlTest.java

 1 package com.test.hqlc;
2
3 import java.text.SimpleDateFormat;
4 import java.util.ArrayList;
5 import java.util.Date;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9 import java.sql.Types;
10
11 import org.hibernate.Query;
12 import org.hibernate.Session;
13
14 import com.test.bean.Student;
15 import com.test.bean.BasDicConstant;
16 import com.test.util.DbUtil;
17
18 public class HqlToSqlTest {
19
20 public static void main(String[] args) {
21
22 // String hql = "from Student";
23 String hql = "from Student where studentName like :stuName and birthDay between :dat1 and :dat2";
24
25
26 List vals = new ArrayList();
27 vals.add("%L%");
28 vals.add("1990-02-28 00:00:00");
29 vals.add("1992-02-28 23:59:59");
30
31 String sql1 = HqlToSql.transHqlToSql(hql);
32 System.out.println("hql转换成sql无参数:"+sql1);
33
34 String sql2 = HqlToSql.transHqlToSql(hql, vals);
35
36 System.out.println("hql转换成sql有参数:"+sql2);
37 System.out.println("转换结果信息: "+HqlToSql.getResultMsg());
38
39 // 有格式化字符串
40 List<TransTemp> list = new ArrayList<TransTemp>();
41
42 // 构造参数
43 TransTemp tt1 = new TransTemp();
44 tt1.setParamSqlType(Types.VARCHAR);
45 tt1.setParamValue("%L%");
46 list.add(tt1);
47
48 TransTemp tt2 = new TransTemp(Types.TIME,"1990-02-28 00:00:00");
49 list.add(tt2);
50
51 TransTemp tt3 = new TransTemp(Types.DATE,new Date(),"yyyy-mm-dd hh24:mi:ss");
52 list.add(tt3);
53
54 String tSql = HqlToSql.formatHqlToSql(hql, list);
55 System.out.println("hql转换成格式化参数的sql: "+tSql);
56
57 }
58 }

6.测试结果:

1 hql转换成sql无参数:select student0_.student_id as student1_0_, student0_.student_name as student2_0_, student0_.student_age as student3_0_, student0_.status as status0_, student0_.birth_Day as birth5_0_ from students student0_ where (student0_.student_name like ?) and (student0_.birth_Day between ? and ?)
2 hql转换成sql有参数:select student0_.student_id as student1_0_, student0_.student_name as student2_0_, student0_.student_age as student3_0_, student0_.status as status0_, student0_.birth_Day as birth5_0_ from students student0_ where (student0_.student_name like '%L%') and (student0_.birth_Day between '1990-02-28 00:00:00' and '1992-02-28 23:59:59')
3 转换结果信息:
4 hql转换成格式化参数的sql: select student0_.student_id as student1_0_, student0_.student_name as student2_0_, student0_.student_age as student3_0_, student0_.status as status0_, student0_.birth_Day as birth5_0_ from students student0_ where (student0_.student_name like '%L%') and (student0_.birth_Day between to_date('1990-02-28 00:00:00','yyyy-mm-dd hh24:mi:ss') and to_date('2014-07-24 17:21:38','yyyy-mm-dd hh24:mi:ss'))

7. 参考资料:

http://coffeelover.iteye.com/blog/462139
http://blog.csdn.net/w_l_j/article/details/7064416
http://www.cnblogs.com/yql1986/archive/2011/09/30/2196621.html?ADUIN=416455569&ADSESSION=1404434624&ADTAG=CLIENT.QQ.5329_.0&ADPUBNO=26349

8.源码 Hibernate02.rar

用Hibernate框架把hql生成可执行的sql语句-Oracle方言的更多相关文章

  1. EF-记录程序自动生成并执行的sql语句日志

    在EntityFramework的CodeFirst模式中,我们想将程序自动生成的sql语句和执行过程记录到日志中,方便以后查看和分析. 在EF的6.x版本中,在DbContext中有一个Databa ...

  2. 使用Mysql中的concat函数或正则匹配来快速批量生成用于执行的sql语句

    背景介绍 今天需要给一张表里面补数据,需要按照行的维度进行update,如果是个别数据那么直接写update语句就可以了,但是场景要求的是将整表的数据进行update,要实现这个需求就不能只靠蛮力了, ...

  3. java:Hibernate框架3(使用Myeclipse逆向工程生成实体和配置信息,hql语句各种查询(使用hibernate执行原生SQL语句,占位符和命名参数,封装Vo查询多个属性,聚合函数,链接查询,命名查询),Criteria)

    1.使用Myeclipse逆向工程生成实体和配置信息: 步骤1:配置MyEclipse Database Explorer: 步骤2:为项目添加hibernate的依赖: 此处打开后,点击next进入 ...

  4. [LINQ2Dapper]最完整Dapper To Linq框架(五)---查看Linq实际执行的SQL

    此例子是使用LINQ2Dapper封装,效率优于EntityFramwork,并且支持.NetFramework和.NetCore框架,只依赖于Dapper支持.net framework4.6.1及 ...

  5. 出错场景是升级oracle驱动,将版本从ojdbc14升级到ojdbc6,hibernate执行原生态sql语句会报如下错误

    出错场景是升级oracle驱动,将版本从ojdbc14升级到ojdbc6,hibernate执行原生态sql语句会报如下错误:org.hibernate.MappingException: No Di ...

  6. django框架 - 实时查看执行的sql语句

    django框架采用的ORM模型,我们可以通过mysql的日志记录实时看到执行的sql语句,具体步骤如下: 第一步:找到mysql的配置文件 第二步:编辑mysql配置文件 第三步:重启mysql 第 ...

  7. thinkPHP框架中执行原生SQL语句的方法

    这篇文章主要介绍了thinkPHP框架中执行原生SQL语句的方法,结合实例形式分析了thinkPHP中执行原生SQL语句的相关操作技巧,并简单分析了query与execute方法的使用区别,需要的朋友 ...

  8. EF 记录执行的sql语句

    最近做了个中等的项目,数据不会很多,开发时间比较紧迫,所以用了EF的框架. 在使用过程中,发现有时候执行的结果不如预期,想看看执行的sql语句为何,遍查找资料,在网上找到了相关辅助类,拿来使用,部署到 ...

  9. 2016/05/13 thinkphp 3.2.2 ① 数据删除及执行原生sql语句 ②表单验证

    [数据删除及执行原生sql语句] delete()  返回受影响的记录条数 $goods -> delete(30);   删除主键值等于30的记录信息 $goods -> delete( ...

随机推荐

  1. KVm中EPT逆向映射机制分析

    2017-05-30 前几天简要分析了linux remap机制,虽然还有些许瑕疵,但总算大致分析的比较清楚.今天分析下EPT下的逆向映射机制.EPT具体的工作流程可参考前面博文,本文对于EPT以及其 ...

  2. 前端框架之SweetAlert

    简介 SweetAlert是一款很好用的弹出框框架 下载 点我下载 导入 博主用的是bootstrap-sweetalert,所以要依赖bootstrap,导入前先导入原生jQuery以及bootst ...

  3. Python3.6编译安装以及python开发之virtualenv与virtualenvwrapper

    Python3.6编译安装 下载python源码包 先到安装目录 cd /opt 下载源码包 wget https://www.python.org/ftp/python/3.6.2/Python-3 ...

  4. (2.4)Mysql之SQL基础——下载与使用测试库

    (2.4)SQL基础——下载与使用测试库 1.查看与下载测试数据库 2.查看安装向导视图 3.安装 [1]安装:解压后用 mysql 命令安装(记得加上set autocommit=1) [2]核验: ...

  5. phpcms发布到服务器修改

    请进行以下步骤的修改: 1.修改/caches/configs/system.php里面所有和域名有关的,把以前的老域名修改为新域名就可以了. 2.进行后台设置->站点管理 对相应的站点的域名进 ...

  6. Mac下 Visual VM 无法检测到本地的Java进程

    我下载的是VisualVM1.4 下载完成之后,在左边栏Local哪里只有VisualVM自己的进程. 我本地启动的eclipse和intelliJ都没有检测到. 网上查阅后都是Window下的解决方 ...

  7. 84. Largest Rectangle in Histogram(直方图最大面积 hard)

    Given n non-negative integers representing the histogram's bar height where the width of each bar is ...

  8. SCP命令只能单项拷贝,另一个方向“RSA host key for 172.16.103.176 has changed and you have requested strict checki Host key verification failed. lost connection”问题

    [dinghuaneng@95 move_data]$ scp * dinghuaneng@172.16.103.176:/home/dinghuaneng@@@@@@@@@@@@@@@@@@@@@@ ...

  9. Lua 数学类

    数学类主要有Vec2(坐标向量).Size(尺寸).Rect(矩形). 创建 在Lua中创建的 Vec2.Size.Rect 都是一个table类型. 其中只有相应的成员变量,没有相关的函数运算. c ...

  10. STM32 HAL库详解 及 手动移植

    源: STM32 HAL库详解 及 手动移植