o2o网站大全asp.net网站
news/
2025/9/29 12:21:20/
文章来源:
o2o网站大全,asp.net网站,crm永久免费,wordpress国产课程主题系列文章目录 本系列课程主要针对于Ehcache缓存框架功能的开发实践全流程技术指南#xff01;
第一节#xff1a;Ehcache缓存框架的基本概念和简介第二节#xff1a;Ehcache缓存框架的配置分析和说明第三节#xff1a;Ehcache缓存框架的缓存方式的探索第四节#xff1a;E…系列文章目录 本系列课程主要针对于Ehcache缓存框架功能的开发实践全流程技术指南
第一节Ehcache缓存框架的基本概念和简介第二节Ehcache缓存框架的配置分析和说明第三节Ehcache缓存框架的缓存方式的探索第四节Ehcache缓存框架的配置分析和说明第五节Ehcache缓存框架的查询分析和说明第六节Ehcache缓存框架的监听器功能扩展第七节Ehcache缓存框架的并发功能的开发第八节Ehcache缓存框架的同步阻塞的开发第九节Ehcache缓存框架的页面缓存的开发第十节Ehcache缓存框架之结合Spring整合 带你一起从零基础进行分析和开发Ehcache框架的实战指南 系列文章目录缓存查询Cache可查询特性机制基于Xml配置xml文件的配置 config代码配置Java代码 指定可搜索的属性机制Xml代码配置 可查询属性类型可查询/可索引能力定义关闭对应查询机制Xml代码配置属性的提取定义自己的AttributeExtractorJava代码Xml代码Xml代码 JavaBeanAttributeExtractorXml代码 ReflectionAttributeExtractor配置案例Xml代码Xml代码Xml代码 DynamicAttributesExtractor实现原理xml代码DynamicAttributesExtractor实际案例Java代码 通过程序指定可查询属性Java代码Java代码 查询创建查询与筛选条件Java代码 Criteria接口获取查询属性Java代码 筛选类型Java代码Criteria的案例 查询内容Java代码 execute方法Results Result结果处理Java代码List集合操作 统计计算维度Java代码 排序Java代码 分组Java代码 让Query不可变对BeanShell的支持Java代码 总结 缓存查询
Ehcache中为我们提供了可以对Cache中缓存的元素进行查找的方式。其逻辑类似于SQL中的查找。通过给定各种限制条件我们可以构造各种复杂的查询然后返回结果集也可以对查询进行分组和排序等。
Cache可查询特性机制
Ehcache中的查询是针对于Cache而言的。但并不是所有的Cache都可以进行查询操作我们需要指定其为一个可查询的Cache之后才可以对该Cache进行查询操作。因为在配置Cache的时候有基于xml文件的配置和基于程序代码的配置所以对应的使一个Cache可查询也有两种方式。
基于Xml配置
当我们的Cache定义是基于Xml文件的配置时我们只需在对应Cache定义下声明一个子元素searchable即可使当前Cache拥有可查询的功能。
xml文件的配置
cache namesearchableCache maxBytesLocalHeap100M searchable/
/cache config代码配置
基于代码的配置是通过新建Searchable对象然后指定需要设置为可查询Cache对应的CacheConfiguration的Searchable对象为我们新建的Searchable对象即可。
Java代码 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); } 指定可搜索的属性机制
配置了Cache可查询后我们还需要配置当前Cache可以对哪些属性进行查询即可以把哪些属性作为条件来对Cache进行查询。在Ehcache中使用一个net.sf.ehcache.search.Attribute来表示一个可查询的属性。这些可查询的属性可以是我们的key、value或者它们对应的属性。定义可查询属性是通过searchable元素的子元素searchAttribute来定义的如
Xml代码配置
cache nameuserCache maxBytesLocalHeap50M searchable searchAttribute namename/ /searchable
/cache 其中name表示我们所定义的可查询属性的名称是必须指定的属性。这里会通过属性提取机制提取key或者value中name所对应的属性这里是name属性来进行索引。关于属性提取机制将在后续讲解。
可查询属性类型
一下属性都可以用来作为Cache的可查询属性它必须是以下类型之一
数据类型描述Boolean代表布尔类型的对象。值可以是true或false。Byte代表一个8位的有符号整数。它的值可以在-128到127之间。Short代表一个16位的有符号整数。它的值可以在-32768到32767之间。Character代表一个单个的16位Unicode字符。Integer代表一个32位的有符号整数。它的值可以在-2147483648到2147483647之间。Long代表一个64位的有符号整数。它的值可以在-9223372036854775808到9223372036854775807之间。Float代表一个单精度32位的IEEE 754浮点数。Double代表一个双精度64位的IEEE 754浮点数。String代表一串字符。它是Java里面最常用的数据类型。java.util.Date此类表示特定的瞬间精确到毫秒。它主要用于表示日期和时间。java.sql.Date此类继承自java.util.Date主要用于JDBC中以与SQL DATE类型交互。Enum代表了Java中的枚举类型用于声明一组预定义的常量。
可查询/可索引能力定义
默认情况下系统会自动把我们存入可查询Cache中元素的key和value作为可查询属性命名为key和value当它们是以上可查询类型时我们可以直接对它们进行查询。
关闭对应查询机制
如果不需要默认将我们的key和value作为可查询属性的话我们可以在指定Cache为一个可查询Cache时指定searchable元素的keys属性和values属性为false即可。如
Xml代码配置
cache namesearchableCache maxBytesLocalHeap100M
. searchable keysfalse valuesfalse/
/cache 属性的提取
当我们的key或者value不是可查询类型然而我们又希望对它们进行查询时我们就需要把key或者value中的属性提取出来作为Cache的一个可查询属性。这是通过AttributeExtractor来进行的AttributeExtractor是一个接口其中只定义了一个方法Object attributeFor(Element element, String attributeName)。其返回值必须是可查询属性类型之一。当然返回null也是可以的。下面我们来看看如何定义自己的AttributeExtractor。
定义自己的AttributeExtractor
假设我们有一个名叫userCache的缓存其中存放的元素值都是一个User对象。而我们的User对象有一个String类型的name属性。假设我们现在指定了我们的userCache的一个可查询属性为user而其真正对应的内容是我们的Element中存放的value的name。那么这个时候我们的AttributeExtractor实现大概会是这个样子
Java代码
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属性即可。
Xml代码
cache nameuserCache maxBytesLocalHeap50M searchable searchAttribute nameuser classcom.xxx.UserAttributeExtractor/ /searchable
/cache 之后我们通过user属性来查询时就可以通过User对象的name属性来过滤一些结果集了。如果我们的AttributeExtractor还需要接收其它的参数的话我们可以通过searchAttribute元素的properties属性来指定其对应的参数是键值对的形式中间用等号“”隔开多个参数之间用逗号隔开。如
Xml代码
cache nameuserCache maxBytesLocalHeap50M searchable searchAttribute nameuser classcom.xxx.UserAttributeExtractor propertiesa1,b2/ /searchable
/cache 指定了properties属性后我们对应的AttributeExtractor必须给定一个以Properties对象为参数的构造方法才可以接收到这些指定的参数。
除了定义自己的属性提取实现类之外Ehcache还为我们提供了一些实现类。包括KeyObjectAttributeExtractor、ValueObjectAttributeExtractor这两个属性提取器就是默认情况下Ehcache用来把key和value提取为一个可查询属性的方式。此外还有JavaBeanAttributeExtractor和ReflectionAttributeExtractor。
JavaBeanAttributeExtractor
当定义一个可查询属性searchAttribute只指定其name属性系统所使用的AttributeExtractor就是JavaBeanAttributeExtractor。该AttributeExtractor会从元素的key或者value中取searchAttribute的name属性值所对应的属性。
如果我们有如下这样一个可查询缓存的定义Ehcache在给可查询属性address建立索引时就会获取元素key的address属性或者value的address属性来作为查询属性address的值。
Xml代码
cache namesearchableCache maxBytesLocalHeap100M searchable keysfalse valuesfalse searchAttribute nameaddress/ /searchable
/cache 注意使用JavaBeanAttributeExtractor时如果key和value中都包含可查询属性则系统会抛出异常如果都不包含的话也会抛出异常。 ReflectionAttributeExtractor
当我们定义一个可查询属性searchAttribute时指定了expression属性时系统就会使用ReflectionAttributeExtractor来提取属性的值。此属性提取器是通过反射来提取属性值的。expression必须以key、value或element开始然后中间以点“.”来连接它们所对应的属性或方法以及属性的属性方法的方法。key表示元素的keyvalue表示元素的valueelement表示元素本身。
配置案例
查询属性address的值是对应的value的address属性。
Xml代码
cache namesearchableCache maxBytesLocalHeap100M searchable keysfalse valuesfalse searchAttribute nameaddress expressionvalue.address/ /searchable
/cache 查询属性address的值是对应的value的extraInfo属性的getAddress()方法的返回值。
Xml代码
cache namesearchableCache maxBytesLocalHeap100M searchable keysfalse valuesfalse searchAttribute nameaddress expressionvalue.extraInfo.getAddress()/ /searchable
/cache 3.查询属性hitCount的值是对应的element的getHitCount()方法的返回值。
Xml代码
cache namesearchableCache maxBytesLocalHeap100M searchable keysfalse valuesfalse searchAttribute namehitCount expressionelement.getHitCount()/ /searchable
/cache DynamicAttributesExtractor
上面介绍的AttributeExtractor都是在Cache实例化之前定义的其会在Cache实例化时初始化这些可查询属性。而DynamicAttributesExtractor允许我们在Cache实例化后添加可查询属性。
实现原理
DynamicAttributesExtractor是一个接口它跟AttributeExtractor接口没有任何关系。该接口中仅定义了一个方法attributesFor()该方法将接收一个Element对象作为参数然后返回一个将作为可查询属性的Map该Map的key对应可查询属性的名称而value则对应可查询属性的值。那么我们在实现DynamicAttributesExtractor接口时只需要实现attributesFor()方法即可。
使用DynamicAttributeExtractor时我们的Cache对应的Searchable必须是支持该提取器才行这是通过Searchable对象的allowDynamicIndexing属性来指定的使用xml配置时该属性是直接配置在searchable元素上的而使用程序来定义时则需要通过Searchable对象来指定了。
之后我们需要把它注册给我们的Cache。通过Cache的registerDynamicAttributesExtractor()方法我们就可以给Cache注册一个动态的属性提取器了该提取器将在往Cache中put或者replace元素时被调用。
xml代码
cache nameuserCache maxBytesLocalHeap50M searchable allowDynamicIndexingtrue searchAttribute namename expressionvalue.getName()/ /searchable
/cache 上面定义了如下这样一个专门用来缓存User的Cache其中User中含有属性name。我们在定义该Cache的时候即指定了其是一个可查询的Cache同时通过指定allowDynamicIndexing为true使其支持动态属性提取我们还给该Cache指定了一个可查询属性name。
DynamicAttributesExtractor实际案例
我们在userCache初始化后给其注册了一个DynamicAttributesExtractor在DynamicAttributesExtractor实现类中我们实现了attributesFor方法在该方法体内我们构造了一个Map并往其中放入了一个key为hitCount的元素。
Java代码
Test
public void dynamicExtractor() { CacheManager cacheManager CacheManager.create(); Cache userCache cacheManager.getCache(userCache); userCache.registerDynamicAttributesExtractor(new DynamicAttributesExtractor() { Override public MapString, Object attributesFor(Element element) { MapString, Object attrMap new HashMapString, Object(); attrMap.put(hitCount, element.getHitCount()); return attrMap; } }); this.listSearchableAttrs(userCache); //key、value和name userCache.put(new Element(1, new User())); this.listSearchableAttrs(userCache); //key、value、name和hitCount
} /** * 输出当前Ehcache中可查询的属性 * param cache */
private void listSearchableAttrs(Ehcache cache) { SetAttribute attrSet cache.getSearchAttributes(); for (Attribute attr : attrSet) { System.out.println(attr.getAttributeName()); }
} 当我们往userCache中put或者replace元素的时候就会触发我们注册的DynamicAttributesExtractor的attributesFor方法然后Ehcache会对返回的动态可查询属性hitCount进行索引。在下面的代码中我们的在给userCache注册了DynamicAttributesExtractor之后马上列出其中包含的可查询属性这个时候肯定只会包含预定义好的key、value和name因为我们注册的DynamicAttributesExtractor还没有被执行。之后往其中放入元素之后userCache中包含的可查询属性才会有通过DynamicAttributesExtractor返回的hitCount。
一个Cache只能注册有一个DynamicAttributesExtractor当同时注册多个时后者会将前者覆盖。但是DynamicAttributesExtractor和其它AttributeExtractor是可以并存的所以因为其它AttributeExtractor是在Cache初始化前定义的所以DynamicAttributesExtractor不能返回已经通过AttributeExtractor提取过的同名属性。
通过程序指定可查询属性
通过前面的内容我们知道设置可查询属性时除了DynamicAttributesExtractor可以在Cache初始化后再添加可查询属性外我们的可查询属性必须是在Cache初始化之前进行指定否则在对Cache进行查询时我们就不能使用该查询属性进行查询。如下面这一段代码我们在Cache初始化后通过获取其配置信息再往其对应的Searchalbe对象中新增一个名叫hello的查询属性那么我们在今后对该Cache进行查询时将不能使用hello属性进行查询。
Java代码
Test
public void setSearchAttrInProgram() { CacheManager cacheManager CacheManager.create(); Cache cache cacheManager.getCache(searchableCache); CacheConfiguration cacheConfig cache.getCacheConfiguration(); Searchable searchable cacheConfig.getSearchable(); SearchAttribute searchAttribute new SearchAttribute(); searchAttribute.name(hello); searchable.addSearchAttribute(searchAttribute); this.listSearchableAttrs(cache);
} 由于定义非动态查询属性时需要在Cache初始化时定义所以当我们需要在程序中定义查询属性时对应的Cache也需要是在程序中声明的才行。下面是在程序中指定可查询属性的一个示例。
Java代码
Test
public void setSearchAttrInProgram() { CacheManager cacheManager CacheManager.create(); CacheConfiguration cacheConfig new CacheConfiguration(); cacheConfig.name(cacheName).maxBytesLocalHeap(100, MemoryUnit.MEGABYTES); //新建一个Searchable对象 Searchable searchable new Searchable(); //给Cache配置Searchable对象表明该Cache是一个可查询的Cache cacheConfig.searchable(searchable); //新建一个查询属性 SearchAttribute searchAttribute new SearchAttribute(); //指定查询属性的名称和属性提取器的类名 searchAttribute.name(查询属性名称); //searchAttribute.className(属性提取器的类名); //Searchalbe对象添加查询属性 searchable.addSearchAttribute(searchAttribute); //使用CacheConfig创建Cache对象 Cache cache new Cache(cacheConfig); //把Cache对象纳入CacheManager的管理中 cacheManager.addCache(cache); this.listSearchableAttrs(cache);
} 查询
在Ehcache中是通过一个net.sf.ehcache.search.Query对象来表示一个查询的通过该对象我们可以对缓存中的元素进行查询查询条件就是我们之前定义好的可查询属性而查询结果可以是缓存的key、value或可查询属性也可以是针对于可查询属性的一些统计结果。
创建查询与筛选条件
在对Cache进行查询前我们需要先创建一个Query对象。Query对象是通过EhCache接口定义的createQuery()方法创建的Cache类对它进行了实现。有了Query对象之后我们需要使用Query对象的addCriteria(Criteria criteria)方法给该Query对象添加一些限制条件来对其中缓存的元素进行筛选否则返回的结果将是针对于所有的缓存元素的。
Java代码
Test
public void search () { CacheManager cacheManager CacheManager.create(); Cache userCache cacheManager.getCache(userCache); User user; for (int i0; i10; i) { user new User(i, name(i%2), 30i); userCache.put(new Element(user.getId(), user)); } Query query userCache.createQuery();
} Criteria接口
Criteria是一个接口在net.sf.ehcache.search.expression定义了其一系列的实现类我们也可以直接通过new一个Criteria实现类的实例来对Query结果进行筛选。但通常我们不需要这样做因为Ehcache中已经为我们实现了的Criteria通常已经可以满足我们的需求了。Ehcache中代表查询属性的Attribute类已经为我们提供了获取针对于该属性的各种Criteria的方法。好现在我们已经知道了可以通过查询属性直接获取到针对于该属性的限制Criteria对象那么我们该如何获取查询属性呢
获取查询属性
获取查询属性Attribute主要有两种方式
直接new一个Attribute实例对象通过Ehcache接口定义的getSearchAttribute(String attrName)获取到可查询缓存中对应属性名称的可查询属性对象Attribute。
常用的还是通过getSearchAttribute(String attrName)方法来获取对应的查询属性Attribute。 当调用可查询Cache的getSearchAttribute(String attrName)方法来获取当前缓存的可查询属性时如果对应名称的可查询属性不存在则会抛出异常。
Java代码
CacheManager cacheManager CacheManager.create();
Cache cache cacheManager.getCache(userCache);
AttributeString name cache.getSearchAttribute(name); Attribute类使用了泛型定义其表示当前属性值的类型。
筛选类型
有了可查询属性Attribute之后我们就可以通过Attribute类定义的一系列方法获取到当前Attribute的某种限制从而对Query的查询结果进行筛选。如我们要筛选name为“name1”的查询结果时我们可以通过name.eq(“name1”)来进行筛选。
Java代码
public void search2() { CacheManager cacheManager CacheManager.create(); Cache userCache cacheManager.getCache(userCache); User user; for (int i0; i10; i) { user new User(i, name(i%2), 30i); userCache.put(new Element(user.getId(), user)); } //获取名称为name的可查询属性Attribute对象 AttributeString name userCache.getSearchAttribute(name); //创建一个用于查询的Query对象 Query query userCache.createQuery(); //给当前query添加一个筛选条件——可查询属性name的值等于“name1” query.addCriteria(name.eq(name1));
} 接下来我们来看一下Attribute类为我们提供的获取对应Criteria的方法有哪些。
Attribute方法对应Criteria实现类描述betweenBetween属性值在给定的范围之间inInCollection在给定的集合之中neNotEqualTo不等于给定的值eqEqualTo等于给定的值ltLessThan小于给定的值leLessThanOrEqual小于或等于给定的值gtGreaterThan大于给定的值geGreaterThanOrEqual大于或等于给定的值ilikeILike匹配给定的表达式表达式中可以使用“*”来代表任意多个字符使用“”来代表任意一个字符notIlikeNotILike不匹配给定的表达式isNullIsNull等于nullnotNullNotNull不等于null
那当我们要实现与或非的逻辑时怎么办呢Criteria为我们提供了对应的方法分别对应and(Criteria criteria)方法、or(Criteria criteria)方法和not()方法然后这三个方法的返回结果还是一个Criteria它们对应的Criteria实现类分别为And、Or和Not。当我们使用Query的addCriteria(Criteria criteria)方法来添加一个筛选条件时默认都是对应的and操作。
Criteria的案例
下面我们来看一些使用Criteria的例子。先假设我们有如下定义的一个Cache其中存放的元素的value都是一个User对象下面将给出一些针对于该Cache使用Criteria进行筛选查询的一些示例。
cache nameuserCache maxBytesLocalHeap50M searchable searchAttribute namename expressionvalue.getName()/ searchAttribute nameage/ searchAttribute nameunitNo expressionvalue.unit.unitNo/ searchAttribute nameunitName expressionvalue.unit.getUnitName()/ searchAttribute namemobile expressionvalue.getMobile()/ searchAttribute namehitCount expressionelement.getHitCount()/ /searchable
/cache 1、年龄在25岁到35岁之间且属于单位002的。
AttributeInteger age userCache.getSearchAttribute(age);
AttributeString unitNo userCache.getSearchAttribute(unitNo);
query.addCriteria(age.between(25, 35).and(unitNo.eq(002)));
//或者使用两次addCriteria
// query.addCriteria(age.between(25, 35)).addCriteria(unitNo.eq(002));2、属于单位002或者单位003手机号码以137开始且年龄大于35岁的。
AttributeInteger age userCache.getSearchAttribute(age);
AttributeString unitNo userCache.getSearchAttribute(unitNo);
AttributeString mobile userCache.getSearchAttribute(mobile);
query.addCriteria(age.gt(35).and(unitNo.eq(002).or(unitNo.eq(003))).and(mobile.ilike(137*))); 3、不属于单位002且年龄小于30的。
AttributeInteger age userCache.getSearchAttribute(age);
AttributeString unitNo userCache.getSearchAttribute(unitNo);
query.addCriteria(unitNo.ne(002).and(age.lt(30)));
//或者使用not()方法
query.addCriteria(unitNo.eq(002).not().and(age.lt(30))); 查询内容
一个Query在查询之前我们必须告诉它需要查询什么内容也就是说查询的结果中会包含哪些信息。如果在执行查询操作之前没有告诉Query我们要查询什么内容Ehcache将抛出异常。可以查询的内容包括缓存中存入元素的key、value可查询属性对应的值以及针对于当前查询结果中某个可查询属性的统计信息。针对于这四种可以查询内容Query中提供了四个include方法来表示当前Query的查询结果中会包含对应的内容。下面用一个表格来做个展示。
Query方法描述includeKeys()查询结果中包含所存元素的keyincludeValues()查询结果中包含所存元素的valueincludeAttribute(Attribute?… attributes)查询结果中要包含的可查询属性includeAggregator(Aggregator… aggregators)查询结果中所要包含的统计信息关于Aggregator将在后文介绍统计的时候进行讲解
如下的代码表示我们的查询结果中会包含元素的key、可查询属性name和age对应的值。
Java代码
AttributeString name userCache.getSearchAttribute(name);
AttributeInteger age userCache.getSearchAttribute(age);
query.includeAttribute(name, age); 在实际应用中为了让我们的程序具有更好的性能我们的查询结果最好只包含我们需要的信息。如只需要获取某个属性的值就不必返回整个value。
execute方法
有了Query之后我们就可以来执行对应的查询操作获取返回的查询结果。通过调用Query的execute()方法就可以对当前Query执行查询操作并获取其返回的结果。Ehcache中使用一个Results接口来代表一个Query的查询结果使用Result接口来代表对应的一条记录。
Results Result Results中定义了一个方法all()用于返回查询出来的所有Result组成的List查询的缓存中有多少元素满足查询条件查询结果Results中就会包含多少个Result对象。 Result中定义有getKey()、getValue()、getAttribute()和getAggregatorResults()方法用于获取查询结果中对应元素的key、value、可查询属性对应的值以及针对于当前查询的统计信息组成的List。
Results和Result这两个接口Ehcache中都已经存在对应的实现了我们在使用时只要直接利用接口来进行操作就可以了。
结果处理
如果查询结果中不包含对应的信息那么在Result调用对应方法获取信息时将抛出异常。Results针对于查询结果中是否包含这四方面的信息给我们提供了四个has方法hasKeys()、hasValues()、hasAttributes()和hasAggregators()。
Java代码
//执行查询操作返回查询结果Results
Results results query.execute();
//获取Results中包含的所有的Result对象
ListResult resultList results.all();
if (resultList ! null !resultList.isEmpty()) { for (Result result : resultList) { //结果中包含key时可以获取key if (results.hasKeys()) { result.getKey(); } //结果中包含value时可以获取value if (results.hasValues()) { result.getValue(); } //结果中包含属性时可以获取某个属性的值 if (results.hasAttributes()) { AttributeString attribute userCache.getSearchAttribute(name); result.getAttribute(attribute); } //结果中包含统计信息时可以获取统计信息组成的List if (results.hasAggregators()) { result.getAggregatorResults(); } }
} 当然如果你已经清楚的知道了查询结果中已经包含了key时你在获取key前就可以不用调用Results的hasKeys()方法进行判断了其它结果也一样。
List集合操作
Results中的all()方法可以返回当前查询的结果中的所有Result组成的List。另外Results中还提供了一个range(int start, int count)方法用于获取当前结果集的一个子集其底层默认实现使用的是List的subList()方法。该方法可以用于对查询结果的分页操作。
默认情况下我们在对Cache进行查询时查询结果将返回所有满足查询条件的记录。当返回的记录非常多时系统可能会因为内存不足而报错。Query中定义了一个maxResults(int maxResults)方法用于限制当前查询返回查询结果的最大记录数。 注意由于元素过期的问题我们查询结果中的元素不一定还存在。当我们利用完Results之后我们需要通过调用Results的discard()方法来释放资源。 统计
Ehcache为我们提供了一个Aggregator接口用于在查询过程中对某个查询属性进行统计。我们可以实现自己的Aggregator也可以使用Ehcache为我们提供的实现类。Ehcache中已经为我们提供了五个Aggregator实现类分别是Min、Max、Sum、Count和Average。看了名称我应该就知道这五个Aggregator分别是做什么用的。
计算维度
Min是求最小值、Max是求最大值、Sum是求和、Count是计数、Average是求平均值。那么在使用这五个Aggregator时也是非常方便的因为我们的Attribute已经为我们针对这五个Aggregator定义了对应的方法。方法名称就是对应Aggregator实现类简称的首字母小写如Min在Attribute中就对应min()方法。
当我们需要对某个查询属性进行统计时我们需要把对应的Aggregator通过调用Query的includeAggregator()方法添加到查询的结果中。
Java代码
//创建一个用于查询的Query对象
Query query userCache.createQuery();
AttributeInteger age userCache.getSearchAttribute(age);
//查询结果中包含age的平均值和age的最大值
query.includeAggregator(age.average(), age.max());
Results results query.execute();
ListResult resultList results.all();
if (resultList ! null !resultList.isEmpty()) { //每一个查询结果Result中都会包含对查询结果的统计信息。 Result result resultList.get(0); //多个统计信息将会组成一个List进行返回 ListObject aggregatorResults result.getAggregatorResults(); Number averageAge (Number)aggregatorResults.get(0); Integer maxAge (Integer)aggregatorResults.get(1); System.out.println(averageAge --- maxAge);
} 当我们的查询结果中只包含有统计信息时我们的查询结果Results中只会有一条记录即一个Result对象。当包含其它信息时查询结果就可能会有多条记录而且每条记录中都会包含有对应的统计信息。
排序
Ehcache中对于Cache的查询也是可以进行排序的这是通过Query的addOrderBy()方法来指定的。该方法接收两个参数第一个参数表示需要进行排序的属性Attribute第二个参数是排序的方向Direction。Direction有两个可选值Direction.ASCENDING和Direction.DESCENDING。当需要对多个属性进行排序时则需要调用多次addOrderBy()方法。
Java代码
AttributeString unitNo userCache.getSearchAttribute(unitNo);
AttributeInteger age userCache.getSearchAttribute(age);
//查询结果按部门编号的升序和年龄的降序进行排列
query.addOrderBy(unitNo, Direction.ASCENDING).addOrderBy(age, Direction.DESCENDING); 分组
Ehcache也支持对查询的缓存进行分组。这是通过Query的addGroupBy()方法来定义的该方法接收一个Attribute作为参数表示要对哪个Attribute进行分组当需要对多个Attribute进行分组时则需要调用多次addGroupBy()方法。使用分组的语法基本上跟SQL里面分组的语法是一样的当使用分组时查询结果只能包含分组的属性和统计信息统计信息是对分组后的情况进行统计。唯一不同的是Ehcache中查询分组时无法对分组后的情况进行筛选。
Java代码
//创建一个用于查询的Query对象
Query query userCache.createQuery();
AttributeString unitNo userCache.getSearchAttribute(unitNo);
AttributeInteger age userCache.getSearchAttribute(age);
//对单位编号进行分组
query.addGroupBy(unitNo);
//各单位年龄的平均值、最大值以及人数。
query.includeAggregator(age.average(), age.max(), age.count());
//查询结果中还包含单位编码
query.includeAttribute(unitNo);
Results results query.execute();
ListResult resultList results.all();
if (resultList ! null !resultList.isEmpty()) { for (Result result : resultList) { String unitNoVal result.getAttribute(unitNo); //多个统计信息将会组成一个List进行返回 ListObject aggregatorResults result.getAggregatorResults(); Number averageAge (Number)aggregatorResults.get(0); Integer maxAge (Integer)aggregatorResults.get(1); Integer count (Integer)aggregatorResults.get(2); System.out.println(单位编号 unitNoVal --- averageAge maxAge count); }
} 让Query不可变
默认情况下我们的Query可以在执行后修改某些属性后继续查询。但是一旦我们调用了Query的end()方法之后我们将不能够再更改Query的一些属性。这包括调用include来定义返回结果中需要包含的信息、指定排序的属性、指定分组的属性、添加Criteria限制条件和调用maxResults()方法指定最大返回记录数。
对BeanShell的支持
BeanShell是用Java写的能够对Java字符串表达式进行解释执行的一个工具。如果在实际应用中我们需要让用户来自定义查询的脚本时我们就可以使用BeanShell来对查询脚本进行解释执行了。使用BeanShell前我们需加入BeanShell的jar包到类路径笔者下面的示例中使用的是BeanShell2.0的第4个测试版本。
Java代码
Test
2.public void beanShell() throws EvalError { CacheManager cacheManager CacheManager.create(); Cache userCache cacheManager.getCache(userCache); User user; for (int i0; i10; i) { user new User(i, name(i%2), 25i); userCache.put(new Element(user.getId(), user)); } //BeanShell解释器需引入BeanShell相关jar包 Interpreter interpreter new Interpreter(); Query query userCache.createQuery().includeValues(); //Interpreter进行计算的字符串中出现的变量都需要放入Interpreter的环境中 interpreter.set(query, query);//把query放入Interpreter环境中 //把age放入Interpreter环境中 interpreter.set(age, userCache.getSearchAttribute(age)); String queryStr query.addCriteria(age.lt(30)).execute();; //BeanShell执行字符串表达式对userCache进行查询并返回Results Results results (Results)interpreter.eval(queryStr); for (Result result : results.all()) { System.out.println(result); } results.discard();
} 关于BeanShell的更多了解请访问BeanShell的官方网站www.beanshell.org。
总结
纵观整个Ehcahce中对于Cache的查询Query我们可以发现其基本的逻辑和规则与SQL查询是一样的。可以进行筛选、选择要查询的结果、统计、排序和分组。Ehcache中的查询也是先通过Criteria进行筛选再进行分组和排序。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921816.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!