viernes, 21 de mayo de 2010

Configurar una cache con Spring con ehcache


Saben como viene la mano? Yo no tengo ganas de ir a buscar a la base todas las veces los datos que me piden; por qué? Porque es más lento. Lo que nos conviene es usar una cache de datos. Como funciona esto? Fácil cada vez que yo deseo consultar un objeto lo guardo en un lugar, cuando alguien hace la misma consulta no vuelvo a ir a la base sino que lo busco de donde lo guarde “la cache” y si alguien guarda o modifica un objeto limpio la cache para que no traiga datos viejos.
Spring modules es nuestro mejor amigo para configurar cache en spring. Vamos a ver como podemos configurar la cache con anotaciones. Uso anotaciones porque me parece más descriptivo pero podría usar aop (va en gusto)
Primero en mi creo los siguientes beans:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">

<ehcache:config configLocation="classpath:ehcache.xml" />
<ehcache:annotations>
<!—- para metodos cacheables -->
<ehcache:caching id="cache" cacheName="defaultCache" />
<!—- para metodos que borran la cache -->
<ehcache:flushing id="flushCache" cacheNames="defaultCache" when="before" />
</ehcache:annotations>
</beans>

Ahora bien debemos crear el archivo: ehcache.xml
<ehcache >
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="defaultCache"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"
/>

</ehcache>
Ahora con anotaciones indicamos que cacheamos y que borra la cache
@Cacheable(modelId="cache")
public List<T> buscarTodos() {
return this.getHibernateTemplate().find("from " +persistentClass.getName());
}

@Cacheable(modelId="cache")
public T buscarPor(Serializable id) {
return (T) this.getHibernateTemplate().get(persistentClass, id);
}

@Cacheable(modelId="cache")
public List<T> buscarPor(T ejemplo) {
return this.getHibernateTemplate().findByExample(ejemplo);
}

@Cacheable(modelId="cache")
public Long contarTodos() {
Query query = this.getSession().createQuery("select count(*) from "+persistentClass.getName());
return (Long) query.uniqueResult();
}
@CacheFlush(modelId="flushCache")
public void guardar(T entidadPersistible) {
this.getHibernateTemplate().save(entidadPersistible);
}

@CacheFlush(modelId="flushCache")
public void actualizar(T entidadPersistible) {
this.getHibernateTemplate().update(entidadPersistible);
}

@CacheFlush(modelId="flushCache")
public void guardarOActualizar(T entidadPersistible) {
this.getHibernateTemplate().saveOrUpdate(entidadPersistible);
}

@CacheFlush(modelId="flushCache")
public void borrar(T entidadPersistible) {
this.getHibernateTemplate().delete(entidadPersistible);
}
@CacheFlush(modelId="flushCache")
public void borrarPor(Serializable id) {
T entidadPersistible = this.buscarPor(id);
this.getHibernateTemplate().delete(entidadPersistible);
}

Si todo salió bien la aplicación va a usar la cache para estos métodos
Dejo las dependencias de maven:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.springmodules</groupId>
<artifactId>spring-modules-cache</artifactId>
<version>0.8</version>
<exclusions>
<exclusion>
<artifactId>gigaspaces-ce</artifactId>
<groupId>gigaspaces</groupId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>jsk-lib</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>jsk-platform</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>mahalo</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>reggie</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>start</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>boot</artifactId>
</exclusion>
<exclusion>
<groupId>jini</groupId>
<artifactId>webster</artifactId>
</exclusion>
<exclusion>
<groupId>jboss</groupId>
<artifactId>jboss-cache</artifactId>
</exclusion>
<exclusion>
<groupId>jboss</groupId>
<artifactId>jboss-common</artifactId>
</exclusion>
<exclusion>
<groupId>jboss</groupId>
<artifactId>jboss-jmx</artifactId>
</exclusion>
<exclusion>
<groupId>jboss</groupId>
<artifactId>jboss-minimal</artifactId>
</exclusion>
<exclusion>
<groupId>jboss</groupId>
<artifactId>jboss-system</artifactId>
</exclusion>
<exclusion>
<groupId>jcs</groupId>
<artifactId>jcs</artifactId>
</exclusion>
<exclusion>
<groupId>xpp3</groupId>
<artifactId>xpp3_min</artifactId>
</exclusion>
<exclusion>
<groupId>ehcache</groupId>
<artifactId>ehcache</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>