JAVA

          人生若只如初見,何事秋風悲畫扇。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            50 隨筆 :: 25 文章 :: 157 評論 :: 0 Trackbacks

            以下是我在hibernate查詢(通過Spring)中碰到的一個小問題及其解決方法,簡單但實用,希望也有益于各同友。 

            在用hibernate查詢中假如用到一個帶中文的參數,如:

          String?hql? = ? " from?Customer?user?where?1=1?and?userr.mc?like?'%惠止南國%' " ;
          Session?session?
          = ?getHibernateTemplate().getSessionFactory().openSession(); // Spring
          Transaction?tx? = ?session.beginTransaction();
          Query?qry?
          = ?session.createQuery(sql);
          List?returnList?
          = ?qry.list();
          tx.commit();
          session.close();


            在執行過程中在eclpise的console臺中可以看到hibernate經過底層將其譯成SQL后成了:

            select ... from Customer user? where 1=1 and userr.hh like '%??????%'

            的樣子。我試過將其以不同的方式編碼,可是都沒有將其最終以正確的結果返回。暫且不談此方法應該如何寫,我主要是想說通過用另外一種查詢方法:在HQL中綁定參數預編譯機制來解決這個亂碼問題。

            參數綁定機制有如下優點:
            a 安全感,防止惡意用戶非法調用DB的存儲過程
            b 利用底層數據庫編譯SQL的功能,提高數據庫查詢性能。預編譯是指底層數據庫系統只能編譯SQL語句一次,把編譯出來的可執行代碼保存在緩存中,如果有多次執行相同的SQL語句,不需要重新編譯,只要從緩存中讀取即可。

            將上面的執行過程改成如下:

          List?params? = ? new ?ArrayList();
          String?hql?
          = ? " from?Customer?user?where?1=1?and?userr.mc?like?? " ;
          params.add(
          " '% " ? + ?form.get( " zdmlmc " ).toString()? + ? " %' " );
          Object[]?objs?
          = ?params.toArray();
          Session?session?
          = ?getHibernateTemplate().getSessionFactory().openSession();
          Transaction?tx?
          = ?session.beginTransaction();
          Query?qry?
          = ?session.createQuery(sql);
          if ?(objs? == ? null )? // ?判斷是否確認參數名稱
          {
          ?
          if (objs.length > 0 )
          ??
          for ?( int ?i? = ? 0 ;?i? < ?objs.length;?i ++ )?
          ???qry.setParameter(i,?objs[i]);
          }

          List?returnList?
          = ?qry.list();
          tx.commit();
          session.close();


            這樣就可以看到在console中最后所執行的SQL:

            select ... from Customer user? where 1=1 and userr.mc like '%惠止南國%'

            在上面中有這樣的語句:

            qry.setParameter(i, objs[i]);

            這是屬于按參數位置綁定中的綁定任意的參數類型。

            org.hibernate.Query的參數綁定形式可以分為

            1 按參數位置綁定

            2 按參數位置綁定

            Query綁定參數類型可以分為:

            1 參數與持久化類實體綁定

          Customer?cus? = ? new ?Customer();
            
          // 省略其它初始化
            
          // 以下是按參數位置綁定
            query.setEntity( " pa_name " ,customer);
            
          // ?or?
          ???????
          // 按參數位置綁定
            query.setEntity(index_location,customer); // index_location是其在HQL中的下標位置,從0開始


            2 綁定任意類型參數

            上面中的qry.setParameter(...)就是這種類型,我們qry.setParameter(i, objs[i]);中是省略了第三個參數即Hibernate映射類型,如:

            qry.setParameter(i, objs[i],Hibernate.STRING);

            對于有些參數,Hibernate能根據參數值的java類型推斷出對應的映射類型,此時不再要在setParameter()中顯式指定映射類型。如上

            3 將命名參數與一個對象屬性綁定

            setProperties()方法

            個人覺得這個跟ORM技術的ibatis中的SQLMAP有些許相似。它是用setProperties()方法。如:

          String?hql? = ? " from?Customer?user?where?1=1?and?userr.mc?like?:sna " ;
          Customer?cus?
          = ? new ?Customer();
          cus.setMc(
          " 惠止南國 " );
          Session?session?
          = ?getHibernateTemplate().getSessionFactory().openSession();
          Transaction?tx?
          = ?session.beginTransaction();
          List?returnList?
          = ?session.createQuery(sql).setProperties(cus).list();
          tx.commit();
          session.close();

          Attention:對于日期型數據不能用setProperties()方法通過實體來綁定。


          ?

          posted on 2006-10-13 11:44 Jkallen 閱讀(4072) 評論(2)  編輯  收藏 所屬分類: 其它開源

          評論

          # re: 在HQL中繞過中文亂碼查詢 2007-03-07 11:43 小小
          如果hql是動態的呢?有沒有什么好的解決辦法?  回復  更多評論
            

          # re: 在HQL中繞過中文亂碼查詢[未登錄] 2012-06-05 21:21 齊齊
          锿?  \ D e v i c e \ H a r d d i s k V o l u m e 2 \ S y s t e m V o l u m e I n f o r m a t i o n \ _ r e s t o r e { 5 0 6 7 A 8 1 3 - E 8 E A - 4 C 9 C - 8 1 9 E - 3 6 6 E 5 C E D 6 4 7 1 } \ R P 3 8 \ c h a n g e . l o g `  锿珋 9U   \ _ 6 4 1 1 2 5 _ ` ?  锿    :U   \ _ 6 4 1 1 2 5 _    € 0 L   &v/?+F倠??   &v/?+F倠?            $    &v/?+F倠??        !     !     !  _ 6 4 1 1 2 5 _ ?   回復  更多評論
            

          主站蜘蛛池模板: 肥乡县| 衢州市| 泰顺县| 景泰县| 米林县| 乐陵市| 道真| 上杭县| 高阳县| 太白县| 新乐市| 锡林浩特市| 安乡县| 台北市| 星座| 中超| 安顺市| 余庆县| 茶陵县| 花垣县| 莲花县| 彰化县| 安顺市| 社旗县| 东丰县| 玉田县| 康马县| 永泰县| 黄龙县| 永安市| 自贡市| 淮南市| 安陆市| 盘锦市| 天等县| 新源县| 哈尔滨市| 威信县| 沁源县| 金门县| 吉林省|