AST构建Hibernat动态查询

一、效果
java 代码
 
  1. public class HqlCompilerImplTest extends TestCase  
  2. {  
  3.     private IHqlCompiler compiler = new HqlCompilerImpl();  
  4.   
  5.     public void test1()  
  6.     {  
  7.         Hql hql = compiler.compile("from User u where u.username = :username and u.age = :age order by u.username,u.age",  
  8.                 new MapContext());  
  9.         assertEquals("from User u order by u.username,u.age", hql.getHql());  
  10.         assertEquals(0, hql.getParameters().length);  
  11.     }  
  12.   
  13.     public void test2)  
  14.     {  
  15.         MapContext context = new MapContext();  
  16.         context.add("username""ray");  
  17.           
  18.         Hql hql = compiler  
  19.                 .compile(  
  20.                         "from User u where u.username = :username and u.age = :age order by u.username,u.age",  
  21.                         context);  
  22.           
  23.         assertEquals(  
  24.                 "from User u where u.username = :username order by u.username,u.age",  
  25.                 hql.getHql());  
  26.         assertEquals(1, hql.getParameters().length);  
  27.         assertEquals("username", hql.getParameters()[0].getName());  
  28.         assertEquals("ray", hql.getParameters()[0].getValue());  
  29.     }  
  30.   
  31.     public void test3()  
  32.     {  
  33.         MapContext context = new MapContext();  
  34.         context.add("username""ray");  
  35.         context.add("age"new Integer(10));  
  36.           
  37.         Hql hql = compiler  
  38.         .compile(  
  39.                 "from User u where u.username = :username and u.age = :age order by u.username,u.age",  
  40.                 context);  
  41.         assertEquals(  
  42.                 "from User u where (u.username = :username and u.age = :age) order by u.username,u.age",  
  43.                 hql.getHql());  
  44.         assertEquals(2, hql.getParameters().length);  
  45.         assertEquals("username", hql.getParameters()[0].getName());  
  46.         assertEquals("ray", hql.getParameters()[0].getValue());  
  47.         assertEquals("age", hql.getParameters()[1].getName());  
  48.         assertEquals(new Integer(10), hql.getParameters()[1].getValue());  
  49.     }  
  50. }  

二、基本接口
java 代码
 
  1. package com.ayufox.framework.core;  
  2.   
  3. /** 
  4.  * @author ray 
  5.  * 
  6.  */  
  7. public interface Context  
  8. {  
  9.     Object get(String name);  
  10. }  
java 代码
 
  1. package com.ayufox.framework.core.dao.hqlx;  
  2.   
  3. import com.ayufox.framework.core.Context;  
  4. import com.ayufox.framework.core.dao.hql.Hql;  
  5.   
  6. /** 
  7.  * @author ray 
  8.  * 
  9.  */  
  10. public interface IHqlCompiler  
  11. {  
  12.     Hql compile(String hql, Object ... values);  
  13.       
  14.     Hql compile(String hql, Context context);  
  15. }  
三、实现
java 代码
 
  1. package com.ayufox.framework.core.dao.hqlx.ast;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.PrintStream;  
  5. import java.util.Collections;  
  6. import java.util.HashMap;  
  7.   
  8. import org.apache.commons.logging.Log;  
  9. import org.apache.commons.logging.LogFactory;  
  10. import org.hibernate.hql.ast.HqlParser;  
  11.   
  12. import antlr.RecognitionException;  
  13. import antlr.TokenStreamException;  
  14. import antlr.collections.AST;  
  15.   
  16. import com.ayufox.framework.core.Context;  
  17. import com.ayufox.framework.core.cache.Cache;  
  18. import com.ayufox.framework.core.cache.MapCache;  
  19. import com.ayufox.framework.core.dao.hql.Hql;  
  20. import com.ayufox.framework.core.dao.hqlx.DynamicMapContext;  
  21. import com.ayufox.framework.core.dao.hqlx.IHqlCompiler;  
  22. import com.ayufox.framework.core.dao.hqlx.IllegalSyntaxException;  
  23.   
  24. /** 
  25.  * @author ray 
  26.  * 
  27.  */  
  28. public class HqlCompilerImpl implements IHqlCompiler  
  29. {  
  30.     private final static Log LOG = LogFactory.getLog(HqlCompilerImpl.class);  
  31.   
  32.     private Cache astCache = new MapCache(Collections  
  33.             .synchronizedMap(new HashMap()));  
  34.   
  35.     public void setAstCache(Cache astCache)  
  36.     {  
  37.         this.astCache = astCache;  
  38.     }  
  39.   
  40.     /* (non-Javadoc) 
  41.      * @see com.konceptusa.framework.core.dao.hqlx.IHqlCompiler#compile(java.lang.String, java.lang.Object[]) 
  42.      */  
  43.     public Hql compile(String hql, Object... values)  
  44.     {  
  45.         return compile(hql, new DynamicMapContext(values));  
  46.     }  
  47.   
  48.     /* (non-Javadoc) 
  49.      * @see com.konceptusa.framework.core.dao.hqlx.IHqlCompiler#compile(java.lang.String, com.konceptusa.framework.core.Context) 
  50.      */  
  51.     public Hql compile(String hql, Context context)  
  52.     {  
  53.         if (hql == null || context == null)  
  54.         {  
  55.             throw new IllegalArgumentException("hql or context can't be null");  
  56.         }  
  57.   
  58.         AST ast = getRootAST(hql);  
  59.   
  60.         HqlCompileExecutor compilerContext = new HqlCompileExecutor(ast,  
  61.                 context);  
  62.         return compilerContext.build();  
  63.     }  
  64.   
  65.     protected AST getRootAST(String hql)  
  66.     {  
  67.         AST ast = (AST) this.astCache.get(hql);  
  68.         if (ast == null)  
  69.         {  
  70.             ast = createAST(hql);  
  71.             this.astCache.put(hql, ast);  
  72.             if (LOG.isDebugEnabled())  
  73.             {  
  74.                 LOG.debug("get ast[" + ast + "] from cache for hql[" + hql  
  75.                         + "]");  
  76.             }  
  77.         }  
  78.         return ast;  
  79.     }  
  80.   
  81.     private AST createAST(String hql)  
  82.     {  
  83.         HqlParser parser = HqlParser.getInstance(hql);  
  84.         try  
  85.         {  
  86.             parser.statement();  
  87.         }  
  88.         catch (RecognitionException e)  
  89.         {  
  90.             throw new IllegalSyntaxException(e);  
  91.         }  
  92.         catch (TokenStreamException e)  
  93.         {  
  94.             throw new IllegalSyntaxException(e);  
  95.         }  
  96.         AST ast = parser.getAST();  
  97.         parser.getParseErrorHandler().throwQueryException();  
  98.         if (LOG.isDebugEnabled())  
  99.         {  
  100.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  101.             parser.showAst(ast, new PrintStream(baos));  
  102.             LOG.debug("AST:" + new String(baos.toByteArray()));  
  103.         }  
  104.         return ast;  
  105.     }  
  106. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值