本文的目的
用ehcache实现对数据库的对象缓存,并且能够使用SQL直接从缓存中搜索已经缓存的对象。由于SQL语句与EQL(EhcacheSearch Query)在形式上完全不同,我们就需要将SQL翻译成对应的EQL。
这篇文章需要读者对antlr以及ehcache有个基本的了解,本文中不予详细讲述。相关的知识请移步至引用,那里将会提供相关链接与学习心得。
实现过程
废话不多说,其实我们要实现的的上述功能可以看做是一个伪内存数据库。但明显由于ehcahce的一些特性,它肯定不能完全实现真实的数据库功能,一个木桶能装多少水取决于,木桶边上最矮的那片木板长度。
翻看ehcache关于Search功能的那块官方文档,当前支持的一些组合函数如sum,max
,min,coun还有average。而支持的搜索数据类型也只有12种(居然还不支持byte[]类型),支持的搜索操作可以分为两个种类,一个是具有特色的key-value操作(听上去有点像NoSQL,其实就是一个hashmap,这种操作是速度最快的,也是最推荐的,因为其它的搜索操作都要遍历ehcache中所有对象对应的field),另一个是基本的数据库的搜索操作,如and,or,not,between,eq(就是'='操作,以下类似),ne('!='),lt('<'),gt('>'),le('<='),ge('>='),ilike('like')还有in('in').
综上所诉,我们就能搞清楚,我们写出来的这个伪内存数据库能做哪些事,以及对什么样的SQL提供支持了:
-
只能支持SELECT操作(这个好像是废话)。
-
不支持多表,嵌套的查询,union ,jion这样的操作就别想了。这个忘了说了,因为ehcache是根据对象来缓存的,就好像一个对象类型对应数据库里的一张表的,其实是可以通过其他方法实现对多表的查询的,可是要绕这个弯子,对于我来说太复杂了。
-
我们不能够搜索精确的字段,以及对字段操作如SELECTFEILD_1,FEILD_2+1 FROMTABLE_NAME (WHERE CLAUSE). 我们只能应对这样的SELECT* FROM TABLE_NAME (WHERE CLAUSE).跟第二条同样地原因,同样的也可以用其他方法绕过。但我们只考虑最简单的情况。
所以我们能够接受的SQL范式是:SELECT* FROM TABLE_NAME (WHERE CLAUSE) (ORDERBY).精简了就是:FROMTABLE_NAME (WHERE CLAUSE)(ORDERBY).如你所见,这就是我们根据ehcache的特性做出很多妥协后所能够支持的SQL了。
然后我们就要对比SQL与EQL的具体差别,实现用antlr编写SQL->EQL的解析器了。
我们假设有一张USER表,建表语句是: