標籤: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