用Hibernate架構把hql產生可執行檔sql語句-Oracle方言

來源:互聯網
上載者:User

標籤:blog   http   java   使用   os   strong   檔案   資料   

  引言:為什麼這樣的需求,源自公司項目需要,公司的項目使用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:javacrm12     </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.OracleDriver17     </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.Oracle10gDialect24     </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

 View Code

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.