缓存的查询
目录
1. 使Cache可查询
1.1 基于Xml配置
1.2 基于代码的配置
2 指定可搜索的属性
2.1 可查询属性类型
2.2 属性的提取
2.2.1 定义自己的AttributeExtractor
2.2.2 JavaBeanAttributeExtractor
2.2.3 ReflectionAttributeExtractor
2.2.4 DynamicAttributesExtractor
2.3 通过程序指定可查询属性
3 查询
3.1 创建查询与筛选条件
3.1.1 获取查询属性
3.1.2 筛选类型
3.2 查询内容
3.3 结果
3.4 统计
3.5 排序
3.6 分组
3.7 让Query不可变
3.8 对BeanShell的支持
3.9 小结
Ehcache中为我们提供了可以对Cache中缓存的元素进行查找的方式。其逻辑类似于SQL中的查找。通过给定各种限制条件,我们可以构造各种复杂的查询,然后返回结果集,也可以对查询进行分组和排序等。
1. 使Cache可查询
Ehcache中的查询是针对于Cache而言的。但并不是所有的Cache都可以进行查询操作,我们需要指定其为一个可查询的Cache之后才可以对该Cache进行查询操作。因为在配置Cache的时候有基于xml文件的配置和基于程序代码的配置,所以对应的使一个Cache可查询也有两种方式。
1.1 基于Xml配置
当我们的Cache定义是基于Xml文件的配置时,我们只需在对应Cache定义下声明一个子元素searchable即可使当前Cache拥有可查询的功能。
1.2 基于代码的配置
基于代码的配置是通过新建Searchable对象,然后指定需要设置为可查询Cache对应的CacheConfiguration的Searchable对象为我们新建的Searchable对象即可。
- public void test() {
- CacheManager cacheManager = CacheManager.create();
- CacheConfiguration cacheConfig = new CacheConfiguration();
- cacheConfig.name("cache1").maxBytesLocalHeap(100, MemoryUnit.MEGABYTES);
- Searchable searchable = new Searchable();
- //指定Cache的Searchable对象。
- cacheConfig.searchable(searchable);
- //如下指定也行
- // cacheConfig.addSearchable(searchable);
- Cache cache1 = new Cache(cacheConfig);
- cacheManager.addCache(cache1);
- }
2 指定可搜索的属性
配置了Cache可查询后,我们还需要配置当前Cache可以对哪些属性进行查询,即可以把哪些属性作为条件来对Cache进行查询。在Ehcache中使用一个net.sf.ehcache.search.Attribute来表示一个可查询的属性。这些可查询的属性可以是我们的key、value或者它们对应的属性。定义可查询属性是通过searchable元素的子元素searchAttribute来定义的,如:
- <cache name="userCache" maxBytesLocalHeap="50M">
- <searchable>
- <searchAttribute name="name"/>
- </searchable>
- </cache>
其中name表示我们所定义的可查询属性的名称,是必须指定的属性。这里会通过属性提取机制提取key或者value中name所对应的属性,这里是name属性,来进行索引。关于属性提取机制将在后续讲解。
2.1 可查询属性类型
并不是所有的属性都可以用来作为Cache的可查询属性,它必须是以下类型之一:
l Boolean
l Byte
l Short
l Character
l Integer
l Long
l Float
l Double
l String
l java.util.Date
l java.sql.Date
l Enum
默认情况下,系统会自动把我们存入可查询Cache中元素的key和value作为可查询属性,命名为key和value,当它们是以上可查询类型时我们可以直接对它们进行查询。如果不需要默认将我们的key和value作为可查询属性的话,我们可以在指定Cache为一个可查询Cache时指定searchable元素的keys属性和values属性为false即可。如:
- <cache name="searchableCache" maxBytesLocalHeap="100M">
- <searchable keys="false" values="false"/>
- </cache>
2.2 属性的提取
当我们的key或者value不是可查询类型,然而我们又希望对它们进行查询时,我们就需要把key或者value中的属性提取出来作为Cache的一个可查询属性。这是通过AttributeExtractor来进行的,AttributeExtractor是一个接口,其中只定义了一个方法Object attributeFor(Element element, String attributeName)。其返回值必须是可查询属性类型之一。当然,返回null也是可以的。下面我们来看看如何定义自己的AttributeExtractor。
2.2.1 定义自己的AttributeExtractor
假设我们有一个名叫userCache的缓存,其中存放的元素值都是一个User对象。而我们的User对象有一个String类型的name属性。假设我们现在指定了我们的userCache的一个可查询属性为user,而其真正对应的内容是我们的Element中存放的value的name。(这个需求可能会比较奇怪)。那么这个时候我们的AttributeExtractor实现大概会是这个样子:
- public class UserAttributeExtractor implements AttributeExtractor {
- @Override
- public Object attributeFor(Element element, String attributeName)
- throws AttributeExtractorException {
- User user = (User) element.getObjectValue();
- return user.getName();
- }
- }
定义好了AttributeExtractor之后,我们要告诉Ehcache,缓存userCache的可查询属性user对应的AttributeExtractor是我们定义的UserAttributeExtractor,这只需要指定searchAttribute元素的class属性即可。
- <cache name="userCache" maxBytesLocalHeap="50M">
- <searchable>
- <searchAttribute name="user" class="com.xxx.UserAttributeExtractor"/>
- </searchable>
- </cache>
之后我们通过user属性来查询时就可以通过User对象的name属性来过滤一些结果集了。如果我们的AttributeExtractor还需要接收其它的参数的话,我们可以通过searchAttribute元素的properties属性来指定,其对应的参数是键值对的形式,中间用等号“=”隔开,多个参数之间用逗号隔开。如: