<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    菜園子

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      7 Posts :: 1 Stories :: 31 Comments :: 0 Trackbacks

    在開發的時候,很多時候都遇到過需要動態拼寫SQL,有的是在配置文件中寫SQL,有的是在Java代碼中拼寫SQL,以配置文件拼SQL的可以拿IBatis為代表,但是很多時候是使用Hibernate的,這個時候就想要是Hibernate能像IBatis那樣寫就好了。

    這個時候就想到了模板語言和配置文件的結合。模板引擎可以選擇Velocity,簡單而不失強大,配置文件可以模仿Hibernate的sql-query 的XML文件。

    Sq-query的示例代碼如下(SQL or HQL):

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE dynamic-hibernate PUBLIC "-//ANYFRAME//DTD DYNAMIC-HIBERNATE//EN"
    "http://www.anyframejava.org/dtd/anyframe-dynamic-hibernate-mapping-4.0.dtd">
    <dynamic-hibernate>
        <query name="selectUserSQL">
            <![CDATA[
                SELECT  USER_ID,NAME
                FROM users_table Where 1=1
                #if($name && $name.length() > 1)
                 AND name =:name
                #end
        ]]>
        </query>
        <query name="selectUserHQL">
        <![CDATA[
             FROM users
            Where 1=1
                #if($name && $name.length() > 1)
                    AND name =:name
                #end
            ]]>
        </query>

     

    在系統加載時,需要把配置文件加載到系統中。加載代碼關鍵部分如下:

     1   public class DynamicHibernateImpl implements InitializingBean, ResourceLoaderAware, ApplicationContextAware
     
     
     2       public void afterPropertiesSet() throws Exception {
     3          for (int i = 0; i < fileNames.size(); i++) {
     4             String fileName = ((String) fileNames.get(i)).trim();
     5             if (resourceLoader instanceof ResourcePatternResolver) {                
     6                 try {
     7                     Resource[] resources=((ResourcePatternResolver) resourceLoader).getResources(fileName);
     8                   buildHQLMap(resources);
     9                 } catch (IOException ex) {
    10                     throw new Exception("Could not resolve sql definition resource pattern [" + fileName + "]", ex);
    11                 }
    12             } else {               
    13                 Resource resource = resourceLoader.getResource(fileName);
    14                 buildHQLMap(new Resource[] { resource });
    15             }
    16         }
    17     }
    18  protected void buildHQLMap(Resource[] resources) throws Exception {
    19         for (int i = 0; i < resources.length; i++) {
    20             buildHQLMap(resources[i]);
    21         }
    22     }
    23  private void buildHQLMap(Resource resource) throws Exception {
    24         try {
    25             InputSource inputSource = new InputSource(resource.getInputStream());
    26             org.w3c.dom.Document doc = this.documentLoader.loadDocument(inputSource, nullnull, org.springframework.util.xml.XmlValidationModeDetector.VALIDATION_NONE, false);
    27             Element root = doc.getDocumentElement();
    28             List<Element> querys = DomUtils.getChildElements(root);
    29             for(Element query:querys){
    30                 String queryName = query.getAttribute("name");
    31                 if (StringUtils.isEmpty(queryName)) {
    32                     throw new Exception("DynamicHibernate Service : name is essential attribute in a <query>.");
    33                 }
    34                 if(statements.containsKey(queryName)){
    35                     throw new Exception("DynamicHibernate Service : duplicated query in a <query>."+queryName);
    36                 }
    37                 statements.put(queryName, DomUtils.getTextValue(query));
    38             }
    39         } catch (SAXParseException se) {
    40             throw se;
    41         } catch (IOException ioe) {
    42             throw ioe;
    43         }
    44     }

    Spring的配置文件示例如下:

    <bean id="dynamicHibernate" class="com.company.DynamicHibernateImpl">
    <property name="sessionFactory" ref="sessionFactory" />
    <property name="simpleTemplate" ref="simpleTemplate" />
    <property name="fileNames">
    <list>
    <value>classpath*:hibernate/dynamic/dynamic-hibernate-*.xml</value>
    </list>
    </property>
    </bean>

    下一步是在使用時調用sql并調用模板方法,進行sql動態化。

    還是DynamicHibernateImpl這個類 

     1     public List findList(String queryName, Map params, int pageIndex, int pageSize) throws Exception { 
     2
             Context context = generateVelocityContext(params);
     3         Query query = findInternal(queryName, context);
     4         if (pageIndex > 0 && pageSize > 0) {
     5             query.setFirstResult((pageIndex - 1) * pageSize);
     6             query.setMaxResults(pageSize);
     7         }
     8       return query.list();        
     9     };
    10   private Context generateVelocityContext(Map<String, Object> params) {
    11         VelocityContext context = new VelocityContext();
    12         if (null == params) {
    13             return null;
    14         }
    15         Iterator<String> iterator = params.keySet().iterator();
    16         while (iterator.hasNext()) {
    17             String key = iterator.next();
    18             Object value = params.get(key);
    19             if (null == value) {
    20                 continue;
    21             }           
    22             context.put(key, value);
    23         }
    24         return context;
    25     };
    26  private Query findInternal(String queryName, Context context) throws Exception {
    27         String sql = findSQLByVelocity(queryName, context);
    28         Query query = sessionFactory.getCurrentSession().createQuery(sql);
    29         String[] namedParams = query.getNamedParameters();
    30         setProperties(query, context, namedParams);
    31         return query;
    32     };
    33  private String findSQLByVelocity(String queryName, Context context) throws Exception {
    34         if (context == null)
    35             context = new VelocityContext();
    36         String sql = getSqlByName(queryName);
    37         StringWriter writer = new StringWriter();
    38         Velocity.evaluate(context, writer, "Hibernate", sql);
    39         sql = writer.toString();
    40         return sql;
    41     };
    42 protected String getSqlByName(String queryKey) {
    43         return statements.get(queryKey);
    44     }

    就這些。

    大家也許有更好的方法,歡迎交流。

    QQ:24889356



    QQ:24889356
    posted on 2011-09-08 11:02 GhostZhang 閱讀(513) 評論(0)  編輯  收藏 所屬分類: J2EE首頁技術區

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 日韩一级在线播放免费观看| 2019中文字幕在线电影免费| 国产一精品一aⅴ一免费| 亚洲日韩中文字幕天堂不卡| 久久久久免费精品国产| 国产亚洲精品va在线| 免费观看久久精彩视频| 久久精品国产69国产精品亚洲| 国产免费一区二区三区不卡| 亚洲AV无码成人精品区蜜桃| 免费国产污网站在线观看15| 亚洲av日韩av无码| 18级成人毛片免费观看| 中文字幕无码精品亚洲资源网久久 | 国产在线观看www鲁啊鲁免费| 亚洲国产精品无码久久九九大片| 日韩高清在线免费观看| 精品女同一区二区三区免费播放 | 国产成人高清精品免费软件| 美女尿口扒开图片免费| 曰韩亚洲av人人夜夜澡人人爽| 中文字幕乱码免费看电影| 久久精品国产亚洲av高清漫画| 69天堂人成无码麻豆免费视频| 亚洲精品无码专区| 亚洲午夜av影院| 91香蕉国产线观看免费全集| 亚洲一区二区三区乱码在线欧洲| 免费a级黄色毛片| 久久国产乱子精品免费女| 亚洲一区二区三区在线网站| 免费jjzz在在线播放国产| 在线观看免费无码专区| 亚洲宅男精品一区在线观看| 亚洲毛片网址在线观看中文字幕 | 亚洲中文字幕日产乱码高清app| 性无码免费一区二区三区在线| 亚洲黄页网在线观看| 亚洲色中文字幕无码AV| 国产一卡二卡3卡四卡免费| 日韩在线观看免费完整版视频|