动态加载HQL

标签: 动态加载 hql | 发表时间:2011-09-10 12:25 | 作者:GhostZhang senyo
出处:http://www.blogjava.net/

接上一篇Hibernate 动态HQL(http://www.blogjava.net/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语句后不用重启服务器,立刻看到结果,加快了开发速度。

 

 



GhostZhang 2011-09-10 12:25 发表评论

相关 [动态加载 hql] 推荐:

动态加载HQL

- senyo - BlogJava-首页技术区
Java代码如下:(ReloadableDynamicHibernate.java). 135         private Map qlMap;                //查询的映射. 这样就实现了每次修改SQL or HQL语句后不用重启服务器,立刻看到结果,加快了开发速度.

HQL查询

- - CSDN博客推荐文章
HQL语句与SQL语句相似,其基本的使用习惯也与SQL相同. 由于HQL是面向对象的查询语句,所以它需要从目标对象中查询信息并返回匹配单个实体对象或多个实体对象的集合,而SQL语句是从数据库的表中查找指定信息,返回的是单条信息或多个信息的集合. select "对象.属性名" from "对象" where "过滤条件" group by "对象.属性名" having "分组条件" order by "对象名.属性名".

java动态加载

- - Java - 编程语言 - ITeye博客
第一部分:Java虚拟机启动时,关于类加载方面的一些动作. 当使用java ProgramName.class运行程序时,Java找到JRE,接着找到jvm.dll,把该动态库载入内存,这就是JVM. 然后加载其它动态库, 并激活JVM. JVM激活之后会进行一些初始化工作,之后生成BootstrapLoader,该Class Loader是由C++写的.

Hibernate 的HQL,QBC 查询语言

- - ITeye博客
1.HQL:(Hibernate Query Language) 是面向对象的查询语言. String hql="from Deptas model where mode.deptName='人事部' ";. String hql="from Deptas model where mode.deptName like '%部%' ";.

Hibernate 分页查询 HQL查询

- - ITeye博客
/*  前提介绍:. * SQL: 查询的直接对象是数据库中的表(表的结构)--遵循的是国际数据库公共的标准. 只属于Hibernate 这个ORM 框架,查询的对象不是数据库的表,而是表对应的持久化对象;---操作的是对象. 只属于ORM框架,它是没有SQL出现的查询(动态查询),查询只存在对象操作上.

Hibernate HQL注入攻击入门

- - FreeBuf.COM
SQL注入是一种大家非常熟悉的攻击方式,目前网络上有大量存在注入漏洞的DBMS(如MySQL,Oracle,MSSQL等). 但是,我在网络上找不到针对Hibernate查询语言的相关资源. 因此本文总结了笔者在阅读文档和不断试验过程中的一些经验技巧. Hibernate是一种ORM框架,用来映射与tables相关的类定义(代码),并包含一些高级特性,包括缓存以及继承,通常在Java与.NET中使用(可参考 NHibernate),但在Java生态系统中更受欢迎.

HIVE优化提示-如何写好HQL

- - CSDN博客云计算推荐文章
一、     Hive join优化. 也可以显示声明进行map join:特别适用于小表join大表的时候,SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key. 2.     注意带表分区的join, 如:.

自定义 Hibernate 的 HQL 函数

- - CSDN博客互联网推荐文章
 有时候我们使用一些数据库特有的SQL语法跟HQL有冲突怎么办,看看这个. 标签: HQL  Dialect  MySQL  Hibernate. [1].[代码] MySQLExtendDialect.java  跳至  [1]. * 作者: Winter Lau. * 时间: 2009-4-13.

无刷新动态加载数据,滚动条加载

- - CSDN博客Web前端推荐文章
无刷新动态加载数据,滚动条加载.  滚屏加载更多数据,适合评论等页面. 本例的数据库很简单,一看就明了.     var winH = $(window).height(); //页面可视区域高度  .         var scrollT = $(window).scrollTop(); //滚动条top  .

美团Android DEX自动拆包及动态加载简介

- - 美团技术团队
作为一个android开发者,在开发应用时,随着业务规模发展到一定程度,不断地加入新功能、添加新的类库,代码在急剧的膨胀,相应的apk包的大小也急剧增加, 那么终有一天,你会不幸遇到这个错误:. 生成的apk在android 2.3或之前的机器上无法安装,提示INSTALL_FAILED_DEXOPT.