菜園子

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

          接上一篇Hibernate 動態HQL(http://www.aygfsteel.com/ghostzhang/archive/2011/09/08/358320.html ),開發中經常需要修改SQL或者HQL的語句,但是每次都要重啟服務器才能使之起作用,就想到在使用Spring配置多語言時有一個ReloadableResourceBundleMessageSource.java類,可以配置動態加載多語言文件,為了配合動態HQL并實現修改HQL語句不用重啟服務器,可以參考下這個類的實現。Java代碼如下:(ReloadableDynamicHibernate.java)

            1 public class ReloadableDynamicHibernate{
            2     private final Map<String, XmlHolder> cachedXmls = new HashMap<String, XmlHolder>();
            3     private org.springframework.beans.factory.xml.DocumentLoader documentLoader = new org.springframework.beans.factory.xml.DefaultDocumentLoader();
            4     
            5     public void afterPropertiesSet() throws Exception {
            6         refreshLoad2Cache(true);
            7     };
            8 
            9     protected String getSqlByName(String queryKey) {
           10         refreshLoad2Cache(false);
           11         Collection<XmlHolder> xmlHolders = cachedXmls.values();
           12         for (XmlHolder holder : xmlHolders) {
           13             String qlString = holder.getQl(queryKey);
           14             if (StringUtils.isNotEmpty(qlString)) {
           15                 return qlString;
           16             }
           17         }
           18         throw new RuntimeException("can not find ql in xml.");
           19     };
           20 
           21     private void refreshLoad2Cache(boolean isForce) {
           22         for (int i = 0; i < fileNames.size(); i++) {
           23             String fileName = ((String) fileNames.get(i)).trim();
           24             if (resourceLoader instanceof ResourcePatternResolver) {
           25                 try {
           26                     Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(fileName);
           27                     for (Resource resource : resources) {
           28                         getXmls(resource,isForce);
           29                     }
           30                 } catch (IOException ex) {
           31                     throw new RuntimeException("Could not resolve sql definition resource pattern [" + fileName + "]", ex);
           32                 }
           33             } else {
           34                 Resource resource = resourceLoader.getResource(fileName);
           35                 getXmls(resource,isForce);
           36             }
           37         }
           38     };
           39 
           40     protected XmlHolder getXmls(Resource resource, boolean isForce) {
           41         synchronized (this.cachedXmls) {
           42             String filename = resource.getFilename();
           43             XmlHolder cachedXmls = this.cachedXmls.get(filename);
           44             if (cachedXmls != null && (cachedXmls.getRefreshTimestamp() < 0 || cachedXmls.getRefreshTimestamp() > System.currentTimeMillis())) {
           45                 return cachedXmls;
           46             }
           47             return refreshXmls(resource, cachedXmls, isForce);
           48         }
           49     };
           50 
           51     protected XmlHolder refreshXmls(Resource resource, XmlHolder xmlHolder, boolean isForce) {
           52         String filename = resource.getFilename();
           53         long refreshTimestamp = System.currentTimeMillis();
           54         if (resource.exists()) {
           55             long fileTimestamp = -1;
           56             try {
           57                 fileTimestamp = resource.lastModified();
           58                 if (!isForce && xmlHolder != null && xmlHolder.getFileTimestamp() == fileTimestamp) {
           59                     if (LOGGER.isDebugEnabled()) {
           60                         LOGGER.debug("Re-caching properties for filename [" + filename + "] - file hasn't been modified");
           61                     }
           62                     xmlHolder.setRefreshTimestamp(refreshTimestamp);
           63                     return xmlHolder;
           64                 }
           65             } catch (IOException ex) {
           66                 if (LOGGER.isDebugEnabled()) {
           67                     LOGGER.debug(resource + " could not be resolved in the file system - assuming that is hasn't changed", ex);
           68                 }
           69                 fileTimestamp = -1;
           70             }
           71             try {
           72                 Map qlMap = loadQlMap(resource);
           73                 xmlHolder = new XmlHolder(qlMap, fileTimestamp);
           74             } catch (Exception ex) {
           75                 if (LOGGER.isWarnEnabled()) {
           76                     LOGGER.warn("Could not parse properties file [" + resource.getFilename() + "]", ex);
           77                 }
           78                 xmlHolder = new XmlHolder();
           79             }
           80         } else {
           81             if (LOGGER.isDebugEnabled()) {
           82                 LOGGER.debug("No properties file found for [" + filename + "] - neither plain properties nor XML");
           83             }
           84             xmlHolder = new XmlHolder();
           85         }
           86         xmlHolder.setRefreshTimestamp(refreshTimestamp);
           87         this.cachedXmls.put(filename, xmlHolder);
           88         return xmlHolder;
           89     };
           90 
           91     protected Map<String,String> buildHQLMap(Resource resource) throws Exception {
           92         Map<String, String> qlMap = new HashMap<String, String>();
           93         try {
           94             InputSource inputSource = new InputSource(resource.getInputStream());
           95             org.w3c.dom.Document doc = this.documentLoader.loadDocument(inputSource, nullnull, org.springframework.util.xml.XmlValidationModeDetector.VALIDATION_NONE, false);
           96             Element root = doc.getDocumentElement();
           97             List<Element> querys = DomUtils.getChildElements(root);
           98             for(Element query:querys){
           99                 String queryName = query.getAttribute("name");
          100                 if (StringUtils.isEmpty(queryName)) {
          101                     throw new Exception("DynamicHibernate Service : name is essential attribute in a <query>.");
          102                 }
          103                 if(qlMap.containsKey(queryName)){
          104                     throw new Exception("DynamicHibernate Service : duplicated query in a <query>.");
          105                 }
          106                 qlMap.put(queryName, DomUtils.getTextValue(query));
          107             }
          108         } catch (Exception ioe) {
          109             throw ioe;
          110         }
          111         return qlMap;
          112     };
          113 
          114     protected Map loadQlMap(Resource resource) {
          115         Map qlMap = new HashMap<String, String>();
          116         InputStream is = null;
          117         try {
          118             is = resource.getInputStream();
          119             return buildHQLMap(resource);
          120         } catch (Exception e) {
          121             e.printStackTrace();
          122         } finally {
          123             try {
          124                 if (null != is) {
          125                     is.close();
          126                 }
          127             } catch (Exception e) {
          128                 e.printStackTrace();
          129             }
          130         }
          131         return qlMap;
          132     };
          133 
          134     protected class XmlHolder {
          135         private Map<String, String> qlMap;                //查詢的映射
          136         private long                fileTimestamp    = -1;
          137         private long                refreshTimestamp = -1;
          138         public String getQl(String key) {
          139             if (null != qlMap) {
          140                 return qlMap.get(key);
          141             } else {
          142                 if (LOGGER.isErrorEnabled()) {
          143                     LOGGER.debug("error is occured in getQl.");
          144                 }
          145                 return "";
          146             }
          147         }
          148 
          149         public XmlHolder(Map<String, String> qlMap, long fileTimestamp) {
          150             this.qlMap = qlMap;
          151             this.fileTimestamp = fileTimestamp;
          152         }
          153         public XmlHolder() {
          154         }
          155         public Map<String, String> getQlMap() {
          156             return qlMap;
          157         }
          158         public long getFileTimestamp() {
          159             return fileTimestamp;
          160         }
          161         public void setRefreshTimestamp(long refreshTimestamp) {
          162             this.refreshTimestamp = refreshTimestamp;
          163         }
          164         public long getRefreshTimestamp() {
          165             return refreshTimestamp;
          166         }
          167     }
          168 }        

          Spring 配置如下:


          <bean id="dynamicHibernate" class="com.company.ReloadableDynamicHibernate">
                  <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 or HQL語句后不用重啟服務器,立刻看到結果,加快了開發速度。

           

           



          QQ:24889356
          posted on 2011-09-10 12:25 GhostZhang 閱讀(2379) 評論(3)  編輯  收藏

          Feedback

          # re: 動態加載HQL 2011-09-13 09:07 tb
          恩 不錯啊   回復  更多評論
            

          # re: 動態加載HQL 2011-09-13 16:43 狗籃子
          每次都會讀文件,動態是動態了,是犧牲了效率換來的。  回復  更多評論
            

          # re: 動態加載HQL 2011-09-13 17:04 GhostZhang
          主要是在開發期采用這個辦法,然后運行的時候再換過來。
            回復  更多評論
            


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


          網站導航:
           
          主站蜘蛛池模板: 乳源| 玛沁县| 平湖市| 兴文县| 武胜县| 红安县| 桦甸市| 湖南省| 彝良县| 双辽市| 永州市| 九龙县| 临夏县| 阜城县| 江源县| 集贤县| 周口市| 盈江县| 萨嘎县| 仁寿县| 建阳市| 翼城县| 明星| 彰化县| 麻城市| 密山市| 白河县| 隆回县| 宜兴市| 商南县| 本溪市| 双牌县| 龙井市| 白玉县| 襄垣县| 黄浦区| 会同县| 平南县| 壤塘县| 彝良县| 石泉县|