EHCache学习笔记

介绍:

EHCache 是一个快速的、轻量级的、易于使用的、进程内的缓存。它支持 read-only 和 read/write 缓存,内存和磁盘缓存。是一个非常轻量级的缓存实现,而且从 1.2 之后就支持了集群。

配置:

EHCache的配置非常灵活,可以在声明里配置,也可以在xml、程序中、构造函数中配置。下面在程序中动态的改变Cache的配置,如下:

Cache cache = manager.getCache("sampleCache");
CacheConfiguration config = cache.getCacheConfiguration();
config.setTimeToIdleSeconds(60);
config.setTimeToLiveSeconds(120);
config.setmaxEntriesLocalHeap(10000);
config.setmaxEntriesLocalDisk(1000000);

当然也可以冻结动态的Cache的配置,如下:

Cache cache = manager.getCache("sampleCache");
cache.disableDynamicFeatures();

在xml中将 <ehcache> 元素的属性 dynamicConfigattribute 改为 "false"即可。

多层次Cache的Cache Warming

要在缓存启动的时候同步缓存数据。EHCache2.5以上版本提供了支持,如下:

Replicated caches provide a boot strap mechanism which populates them. For example following is the JGroups bootstrap cache loader:

<bootstrapCacheLoaderFactory

class="net.sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoaderFactory"

properties="bootstrapAsynchronously=true"/>

There are two new bootstrapCacheLoaderFactory implementations: one for standalone caches with DiskStores, and one for Terracotta Distributed caches.

DiskStoreBootstrapCacheLoaderFactory

The DiskStoreBootstrapCacheLoaderFactory loads elements from the DiskStore to the On-Heap Store and the Off-Heap store until either:

<bootstrapCacheLoaderFactory

class="net.sf.ehcache.store.DiskStoreBootstrapCacheLoaderFactory"

properties="bootstrapAsynchronously=true"/>

TerracottaBootstrapCacheLoaderFactory

The TerracottaBootstrapCacheLoaderFactory loads elements from the Terracotta L2 to the L1 based on what it was using the last time it ran. If this is the first time it has been run it has no effect.

<bootstrapCacheLoaderFactory class="net.sf.ehcache.terracotta.TerracottaBootstrapCacheLoaderFactory"

properties="bootstrapAsynchronously=true,

directory=dumps,

interval=5,

immediateShutdown=false,

snapshotOnShutDown=true,

doKeySnapshot=false,

useDedicatedThread=false"/>

当然EHCache的cache也可以配置读拷贝与写拷贝,详细见:copyOnRead and copyOnWrite cache configuration 。

ehcache.xml的配置

EHCache默认到classpath下去找ehcache.xml,如果找不到,则找ehcache-failsafe.xml配置文件,而ehcache-failsafe.xml是打包在的ehcache的jar包中,所以它始终可以被找到。ehcache-failsafe.xml提供了一个非常简单的默认配置,它允许用户在配置chcache.xml之前就可以启动ehcache,其中的配置如下:

<ehcache>

<diskStore path="java.io.tmpdir"/>

<defaultCache

maxEntriesLocalHeap="10000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

maxEntriesLocalDisk="10000000"

diskPersistent="false"

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU"

/>

</ehcache>

BigMemory的介绍与配置

BigMemory是一个纯的java产品,它支持caches使用额外的内存空间来存储堆对象,它以快照式的任务存储(或称off-heap store,离线堆存储),打包在Enterprise Ehcache中,This off-heap store, which is not subject to Java GC, is 100 times faster than the DiskStore and allows very large caches to be created (we have tested this with over 350GB).

配置(Configuring caches to overflow to off-heap.)

Declarative Configuration-说明性的配置(通过xml配置文件)

<ehcache updateCheck="false" monitoring="off" dynamicConfig="false">

<defaultCache maxEntriesLocalHeap="10000"

eternal="true"

memoryStoreEvictionPolicy="LRU"

statistics="false" />

<cache name="sample-offheap-cache"

maxEntriesLocalHeap="10000"

eternal="true"

memoryStoreEvictionPolicy="LRU"

overflowToOffHeap="true"

maxMemoryOffHeap="1G"/>

</ehcache>

注意,NOTE: Dynamically Adding Caches With Fixed-Sized Offheap

If a CacheManager has a pooled offheap setting, caches with fixed-size offheap settings cannot be added dynamically. Dynamic in this case refers to caches that are added programmatically or using the Terracotta Developer Console while the CacheManager is running. A fixed-size offheap setting refers to a setting that specifies a size in bytes.

Programmatic Configuration(程序中配置)

public Cache createOffHeapCache()
{
  CacheConfiguration config = new CacheConfiguration("sample-offheap-cache", 10000)
  .overflowToOffHeap(true).maxMemoryOffHeap("1G");
  Cache cache = new Cache(config);
  manager.addCache(cache);
  return cache;
}

sizing caches

Tuning Ehcache often involves sizing cached data appropriately. Ehcache provides a number of ways to size the different data tiers using simple cache-configuration sizing attributes. These sizing attributes affect local memory and disk resources, allowing them to be set differently on each node.(翻译:调谐Ehcache常常涉及sizing cached 数据的合适性。Ehcache提供了大量的方式配置不同的数据层的大小,使用简单的cache-configuration sizing 属性。这些 sizing 属性会影响本地内存和磁盘资源,对于每个节点允许它们设置不同。)

使用ehcache

向cache取值与设值

示例1:

public class MyDataAccessClass
{
  private final Ehcache cache;
  public MyDataAccessClass(Ehcache cache)
  {
    this.cache = cache;
  }

/* read some data, check cache first, otherwise read from sor */
  public V readSomeData(K key)
  {
     Element element;
     if ((element = cache.get(key)) != null) {
         return element.getValue();
     }
      // note here you should decide whether your cache
     // will cache ‘nulls‘ or not
     if (value = readDataFromDataStore(key)) != null) {
         cache.put(new Element(key, value));
     }
     return value;
  }
  /* write some data, write to sor, then update cache */
  public void writeSomeData(K key, V value)
  {
     writeDataToDataStore(key, value);
     cache.put(new Element(key, value);
  }

示例2:

public class MyDataAccessClass

{

private final Ehcache cache;

public MyDataAccessClass(Ehcache cache)

{

cache.registerCacheWriter(new MyCacheWriter());

this.cache = new SelfPopulatingCache(cache);

}

/* read some data - notice the cache is treated as an SOR.

* the application code simply assumes the key will always be available

*/

public V readSomeData(K key)

{

return cache.get(key);

}

/* write some data - notice the cache is treated as an SOR, it is

* the cache‘s responsibility to write the data to the SOR.

*/

public void writeSomeData(K key, V value)

{

cache.put(new Element(key, value);

}

/**

* Implement the CacheEntryFactory that allows the cache to provide

* the read-through strategy

*/

private class MyCacheEntryFactory implements CacheEntryFactory

{

public Object createEntry(Object key) throws Exception

{

return readDataFromDataStore(key);

}

}

/**

* Implement the CacheWriter interface which allows the cache to provide

* the write-through or write-behind strategy.

*/

private class MyCacheWriter implements CacheWriter

public CacheWriter clone(Ehcache cache) throws CloneNotSupportedException;

{

throw new CloneNotSupportedException();

}

public void init() { }

void dispose() throws CacheException { }

void write(Element element) throws CacheException;

{

writeDataToDataStore(element.getKey(), element.getValue());

}

void writeAll(Collection elements) throws CacheException

{

for (Element element : elements) {

write(element);

}

}

void delete(CacheEntry entry) throws CacheException

{

deleteDataFromDataStore(element.getKey());

}

void deleteAll(Collection entries) throws CacheException

{

for (Element element : elements) {

delete(element);

}

}

}

}

示例3:

EHCacheUtils.java

package com.ttpod.common.tool.cache;

/**

* @classDescription:ehcache工具类

*/

public class EHCacheUtil {

private static CacheManager cacheManager = null;

private static Cache cache=null;

//------------------简化---------------------

/**

* 初始化缓存管理容器

*/

public static CacheManager initCacheManager() {

try {

if (cacheManager == null)

cacheManager = CacheManager.getInstance();

} catch (Exception e) {

e.printStackTrace();

}

return cacheManager;

}

/**

* 初始化缓存管理容器

* @param path ehcache.xml存放的路徑

*/

public static CacheManager initCacheManager(String path) {

try {

if (cacheManager == null){

System.out.println("为进来"+path);

cacheManager = CacheManager.getInstance().create(path);

}

} catch (Exception e) {

e.printStackTrace();

}

return cacheManager;

}

/**

* 初始化cache

*/

public static Cache initCache(String cacheName) {

checkCacheManager();

if(null==cacheManager.getCache(cacheName)){

cacheManager.addCache(cacheName);

}

cache=cacheManager.getCache(cacheName);

return cache;

}

/**

* 添加缓存

* @param key 关键字

* @param value 值

*/

public static void put(Object key,Object value) {

checkCache();

// 创建Element,然后放入Cache对象中

Element element = new Element(key, value);

cache.put(element);

}

/**

* 获取cache

* @param key 关键字

* @return

*/

public static Object get(Object key){

checkCache();

Element element = cache.get(key);

if(null==element){

return null;

}

return element.getObjectValue();

}

//--------------更加方便使用的----------------

//private static CacheManager myManager=null;

//private static Cache myCache=null;

/**

* 初始化缓存

* @param cacheName 缓存名称

* @param maxElementsInMemory 元素最大数量

* @param overflowToDisk 是否持久化到硬盘

* @param eternal 是否会死亡

* @param timeToLiveSeconds 缓存存活时间

* @param timeToIdleSeconds 缓存的间隔时间

* @return缓存

* @throws Exception 异常

*/

public static Cache initCache(String cacheName,int maxElementsInMemory,

boolean overflowToDisk,boolean eternal,long timeToLiveSeconds,

long timeToIdleSeconds) throws Exception{

try {

CacheManager singletonManager = CacheManager.create();

Cache myCache = singletonManager.getCache(cacheName);

if(myCache!=null){

CacheConfiguration config = cache.getCacheConfiguration();

config.setTimeToLiveSeconds(timeToLiveSeconds);

config.setMaxElementsInMemory(maxElementsInMemory);

config.setOverflowToDisk(overflowToDisk);

config.setEternal(eternal);

config.setTimeToLiveSeconds(timeToLiveSeconds);

config.setTimeToIdleSeconds(timeToIdleSeconds);

}

if(myCache==null){

Cache memoryOnlyCache = new Cache(cacheName, maxElementsInMemory, overflowToDisk,

eternal, timeToLiveSeconds, timeToIdleSeconds);

singletonManager.addCache(memoryOnlyCache);

myCache = singletonManager.getCache(cacheName);

}

return myCache;

} catch (Exception e) {

e.printStackTrace();

throw new Exception("init cache "+cacheName+" failed!!!");

}

}

/**

* 初始化cache

* @param cacheName cache的名字

* @param timeToLiveSeconds 有效时间

* @return cache 缓存

* @throws Exception 异常

*/

public static Cache initCache(String cacheName,long timeToLiveSeconds) throws Exception{

try {

CacheManager myManager = CacheManager.create();

Cache myCache = myManager.getCache(cacheName);

if(myCache!=null){

CacheConfiguration config = myCache.getCacheConfiguration();

config.setTimeToLiveSeconds(timeToLiveSeconds);

config.setMaxElementsInMemory(EHCacheConfig.MAXELEMENTSINMEMORY);

config.setMemoryStoreEvictionPolicy(EHCacheConfig.MEMORYSTOREEVICTIONPOLICY);

config.setOverflowToDisk(EHCacheConfig.OVERFLOWTODISK);

config.setEternal(EHCacheConfig.ETERNAL);

config.setTimeToLiveSeconds(timeToLiveSeconds);

config.setTimeToIdleSeconds(EHCacheConfig.TIMETOIDLESECONDS);

config.setDiskPersistent(EHCacheConfig.DISKPERSISTENT);

config.setDiskExpiryThreadIntervalSeconds(0);

}

if(myManager.getCache(cacheName)==null){

myCache = new Cache(

new CacheConfiguration(cacheName, EHCacheConfig.MAXELEMENTSINMEMORY)

.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)

.overflowToDisk(EHCacheConfig.OVERFLOWTODISK)

.eternal(EHCacheConfig.ETERNAL)

.timeToLiveSeconds(timeToLiveSeconds)

.timeToIdleSeconds(EHCacheConfig.TIMETOIDLESECONDS)

.diskPersistent(EHCacheConfig.DISKPERSISTENT)

.diskExpiryThreadIntervalSeconds(0));

myManager.addCache(myCache);

}

return myCache;

} catch (Exception e) {

e.printStackTrace();

throw new Exception("init cache "+cacheName+" failed!!!");

}

}

/**

* 修改缓存

* @param cacheName 缓存名

* @param timeToLiveSeconds 有效时间

* @param maxElementsInMemory 最大数量

* @return真

* @throws Exception 异常

*/

public static boolean modifyCache(String cacheName,

long timeToLiveSeconds,int maxElementsInMemory) throws Exception{

try {

if(StringUtils.isNotBlank(cacheName) && timeToLiveSeconds!=0L

&& maxElementsInMemory!=0){

CacheManager myManager = CacheManager.create();

Cache myCache = myManager.getCache(cacheName);

CacheConfiguration config = myCache.getCacheConfiguration();

config.setTimeToLiveSeconds(timeToLiveSeconds);

config.setMaxElementsInMemory(maxElementsInMemory);

return true;

}else{

return false;

}

} catch (Exception e) {

e.printStackTrace();

throw new Exception("modify cache "+cacheName+" failed!!!");

}

}

/**

* 请求向ehcache中设置值

* @param vesselName 容器名

* @param key 键

* @param value 值

* @return返回真

* @throws Exception 异常

*/

public static boolean setValue(String cacheName,String key, Object value) throws Exception{

try {

EHCacheUtil.initCacheManager();

EHCacheUtil.initCache(cacheName);

EHCacheUtil.put(key, value);

//cacheManager.

return true;

} catch (Exception e) {

e.printStackTrace();

throw new Exception("set cache "+cacheName+" failed!!!");

}

}

/**

* 从ehcache的指定容器中取值

* @param key 键

* @return返回Object类型的值

* @throws Exception 异常

*/

public static Object getValue(String cacheName,String key) throws Exception{

try {

EHCacheUtil.initCacheManager();

EHCacheUtil.initCache(cacheName);

return EHCacheUtil.get(key);

} catch (Exception e) {

e.printStackTrace();

throw new Exception("get cache "+cacheName+" failed!!!");

}

}

/**

* 删除指定的ehcache容器

* @param vesselName

* @return真

* @throws Exception 异常

*/

public static boolean removeEhcache(String cacheName) throws Exception{

try {

initCacheManager();

initCache(cacheName);

removeCache(cacheName);

return true;

} catch (Exception e) {

e.printStackTrace();

throw new Exception("remove cache "+cacheName+" failed!!!");

}

}

//------------------方便调用------------

/**

* 释放CacheManage

*

*/

public static void shutdown() {

cacheManager.shutdown();

}

/**

* 移除cache

* @param cacheName

*/

public static void removeCache(String cacheName){

checkCacheManager();

cache=cacheManager.getCache(cacheName);

if(null!=cache){

cacheManager.removeCache(cacheName);

}

}

/**

* 移除cache中的key

* @param cacheName

*/

public static void remove(String key){

checkCache();

cache.remove(key);

}

/**

* 移除所有cache

*/

public static void removeAllCache(){

checkCacheManager();

cacheManager.removalAll();

}

/**

* 移除所有Element

*/

public static void removeAllKey(){

checkCache();

cache.removeAll();

}

/**

* 获取所有的cache名称

* @return

*/

public static String[]getAllCaches(){

checkCacheManager();

return cacheManager.getCacheNames();

}

/**

* 获取Cache所有的Keys

* @return

*/

public static List getKeys(){

checkCache();

return cache.getKeys();

}

/**

* 检测cacheManager

*/

private static void checkCacheManager(){

if(null==cacheManager){

throw new IllegalArgumentException("调用前请先初始化CacheManager值:EHCacheUtil.initCacheManager");

}

}

private static void checkCache(){

if(null==cache){

throw new IllegalArgumentException("调用前请先初始化Cache值:EHCacheUtil.initCache(参数)");

}

}

public static void main(String[]arg){

//初始化--必须

EHCacheUtil.initCacheManager();

String[]caches=EHCacheUtil.getAllCaches();

for(String cache:caches){

System.out.println(cache);

}

//        //放入Test Cache中

//        EHCacheUtil.initCache("ceshi");

//        EHCacheUtil.put("F", "hello world");

//        //--1111

//        System.out.println(EHCacheUtil.get("F"));

//

//

//        EHCacheUtil.initCacheManager();

//        EHCacheUtil.initCache("Test");

//        EHCacheUtil.put("F", "hello world1");

//

//        //----2222

//        System.out.println(EHCacheUtil.get("F"));

//

//        //初始化--必须

//        EHCacheUtil.initCacheManager();

//        //放入Test Cache中

//        EHCacheUtil.initCache("ceshi");

//        //----3333

//        System.out.println(EHCacheUtil.get("F"));

//

//

//        //初始化--必须

//        EHCacheUtil.initCacheManager();

//        //放入Test Cache中

//        EHCacheUtil.initCache("cassger");

//        //----

//        EHCacheUtil.put("F", "fangs");

//        System.out.println(EHCacheUtil.get("F"));

}

}

EHCacheConfig.java

package com.ttpod.common.tool.cache;

/**

* @className:EHCacheConfig.java

* @classDescription:

*/

public class EHCacheConfig {

/**

* 元素最大数量

*/

public static int MAXELEMENTSINMEMORY=50000;

/**

* 是否把溢出数据持久化到硬盘

*/

public static boolean OVERFLOWTODISK=true;

/**

* 是否会死亡

*/

public static boolean ETERNAL=false;

/**

* 缓存的间隔是时间

*/

public static int TIMETOIDLESECONDS=300;

/**

* 需要持久化到硬盘否

*/

public static boolean DISKPERSISTENT=false;

/**

* 内存存取策略

*/

public static String MEMORYSTOREEVICTIONPOLICY="LFU";

}

hibernate中的二级缓存

命名缓存查询

In addition, a QueryCache can be given a specific name in Hibernate using Query.setCacheRegion(String name). The name of the cache in ehcache.xml is then the name given in that method. The name can be whatever you want, but by convention you should use "query." followed by a descriptive name. E.g.

<cache name="query.AdministrativeAreasPerCountry"

maxEntriesLocalHeap="5"

eternal="false"

timeToLiveSeconds="86400"

overflowToDisk="true"/>

使用缓存查询

For example, let‘s say we have a common query running against the Country Domain. Code to use a query cache follows:

public List getStreetTypes(final Country country) throws HibernateException {

final Session session = createSession();

try {

final Query query = session.createQuery(

"select st.id, st.name"

+ " from StreetType st "

+ " where st.country.id = :countryId "

+ " order by st.sortOrder desc, st.name");

query.setLong("countryId", country.getId().longValue());

query.setCacheable(true);

query.setCacheRegion("query.StreetTypes");

return query.list();

} finally {

session.close();

}

}

The query.setCacheable(true) line caches the query.Thequery.setCacheRegion("query.StreetTypes") line sets the name of the Query Cache. Alex Miller has a good article on the query cache here.

程序中配置ehcache

Differences Between Distributed Cache and Standalone or Replicated Cache

CacheManagers can be configured programmatically with a fluent API. The example below creates a CacheManager with a Terracotta configuration specified in an URL, and creates a defaultCache and a cache named "example".

Configuration configuration = new Configuration()
.terracotta(new TerracottaClientConfiguration().url("localhost:9510"))
.defaultCache(new CacheConfiguration("defaultCache", 100))
.cache(new CacheConfiguration("example", 100)
.timeToIdleSeconds(5)
.timeToLiveSeconds(120)
.terracotta(new TerracottaConfiguration()));
CacheManager manager = new CacheManager(configuration);

The above example looks for sampleTerracottaCache. In ehcache.xml, we need to uncomment or add the following line:

<terracottaConfig url="localhost:9510"/>

This tells Ehcache to load the Terracotta server config from localhost port 9510. For url configuration options, refer to "Adding an URL Attribute" in Terracotta Clustering Configuration Elements. Note: You must have a Terracotta 3.1.1 or higher server running locally for this example.

Next we want to enable Terracotta clustering for the cache named sampleTerracottaCache. Uncomment or add the following in ehcache.xml.

<cache name="sampleTerracottaCache"

maxEntriesLocalHeap="1000"

eternal="false"

timeToIdleSeconds="3600"

timeToLiveSeconds="1800"

overflowToDisk="false">

<terracotta/>

</cache>

That‘s it!

时间: 2024-11-06 09:43:04

EHCache学习笔记的相关文章

Ehcache学习笔记——初识Ehcache

1. Ehcache 的主要特性和集群方案 EHCache EHCache 是一个纯 java 的在进程中的缓存,是 Hibernate 中默认的 CacheProvider,最小的依赖性, 全面的文档和测试,最新版本为 2.0.1. 缓存应用在多个领域并发挥作用,ehcache 可应用于数据库访问缓存,安全认证缓存,web 缓存,soap 和 RESTFul 服务缓存,应用程序持久对象缓存以及分布式缓存. (1)EhCache 的主要特性有: a) 快速: b) 简单: c)多种缓存策略: d

Cache学习笔记汇总

鲁春利的工作笔记,好记性不如烂笔头 Ehcache学习笔记(一)基础入门 http://luchunli.blog.51cto.com/2368057/1726800 Ehcache学习笔记(二)基础入门

mybatis学习笔记(14)-mybatis整合ehcache

mybatis学习笔记(14)-mybatis整合ehcache mybatis学习笔记14-mybatis整合ehcache 分布缓存 整合方法掌握 整合ehcache 加入ehcache的配置文件 ehcache是一个分布式缓存框架 分布缓存 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式) 不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发.所以要使用分布式缓存对缓存数据进行集中管理. mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合.

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

springmvc+mybatis学习笔记(汇总)

springmvc+mybatis学习笔记(汇总) 标签 : springmvc mybaits springmvcmybatis学习笔记汇总 目录 联系作者 笔记分为两大部分:mybatis和springmvc mybatis springmvc 笔记内容主要是mybatis和springmvc的一些基本概念和使用方法,涉及概念介绍.环境搭建.编程细节.运行调试等方面. 这套笔记整体偏入门和应用,适合快速上手,对底层实现和机理并未做过多分析.我后续会研读spring源码,并把学习的收获写成博客

spring data jpa学习笔记一:helloworld

在学习 JPA Spring Data之前,我们有必要了解一下JPA和Spring Data. JPA JPA全称Java Persistence API.即java持久化规范.JPA通过注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. Spring Data Spring Data是Spring框架的一个子项目,就像Spring MVC是Spring的一部分一样.使得数据库访问变得方便和快捷.Spring Data 支持JPA. JPA Spring Data J

vector 学习笔记

vector 使用练习: /**************************************** * File Name: vector.cpp * Author: sky0917 * Created Time: 2014年04月27日 11:07:33 ****************************************/ #include <iostream> #include <vector> using namespace std; int main

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu

jQuery学习笔记(一):入门

jQuery学习笔记(一):入门 一.JQuery是什么 JQuery是什么?始终是萦绕在我心中的一个问题: 借鉴网上同学们的总结,可以从以下几个方面观察. 不使用JQuery时获取DOM文本的操作如下: 1 document.getElementById('info').value = 'Hello World!'; 使用JQuery时获取DOM文本操作如下: 1 $('#info').val('Hello World!'); 嗯,可以看出,使用JQuery的优势之一是可以使代码更加简练,使开