- Advance
Many times in our projects we need to access static data tables, sometimes accessing all the data and sometimes recovering one key element. These calls are the same data again and again, consuming time accessing the database. An important part of our developments is the speed and database accesses are a major penalty. Let's see how to improve the speed using ehcache in accessing methods based on static data tables
- Explanation
In our repository we created the example working properly SVN repository. It´s a maven proyect and We need a local mysql database to make it work. The script of our example is in the Main.java in the svm. With the script you can create you the schema, table and data necessary. To model the table 'Vehicle' will use JPA.
@Entity @Table(name = "VEHICLES") public class Vehicle implements Serializable { private static final long serialVersionUID = -4295164392260587011L; public Vehicle() { super(); } /** * Id */ @Id @Column(name = "IDVEHICLE") private Integer id; /** * Name */ @Column(name = "NAME", nullable = false, length = 45) private String name; /** * Name */ @Column(name = "DESCRIPTION", length = 150) private String description; /** * Constructor * @param id * @param name * @param description */ public Vehicle(Integer id, String name, String description) { super(); this.id = id; this.name = name; this.description = description; } /** * @return the id */ public Integer getId() { return id; } /** * @param id the id to set */ public void setId(Integer id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the description */ public String getDescription() { return description; } /** * @param description the description to set */ public void setDescription(String description) { this.description = description; } @Override public String toString() { return "Vehicle [id=" + this.id + ", name=" + this.name + ", description=" + this.description + "]"; } }And we create a DAO with the methods getAll y getVehicle. We can see how we use the @Cacheable annotation to indicate that the method we want to be cached
@Component("vehicleDAO") @Repository public class VehicleDAO extends AbstractJpaDAOehcache need a configuration file, ehcache.xml, which will in the classpath together spring-config.xml{ public VehicleDAO(){ setClassName(Vehicle.class); } @Cacheable(value = "vehicleCache") public List getAll() { List lstVehicles0 = this.findAll(); return lstVehicles0; } @Cacheable(value = "vehicleCache", key = "#id") public Vehicle getVehicle(Integer id) { Vehicle objVehicle = this.findOne(id); return objVehicle; } public void insert(Vehicle vehicle) { this.save(vehicle); } }
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <!-- Default Cache Configuration, with name 'default' --> <defaultCache maxElementsInMemory="50" eternal="false" overflowToDisk="false" memoryStoreEvictionPolicy="LFU" /> <cache name="vehicleCache" maxElementsInMemory="50" eternal="false" overflowToDisk="false" memoryStoreEvictionPolicy="LFU" /> </ehcache>In this configuration file we create the cache "vehicleCache", which will be used for our methods in VehicleDAO. Now, we show how would the spring-config.xml
<?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:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <cache:annotation-driven /> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="geekzpacho.examples.ehcache" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="showSql" value="false" /> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" /> </bean> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/geekzpacho" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="txManager" /> <context:component-scan base-package="geekzpacho.examples.ehcache" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcache" /> </bean> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml" /> </bean> <bean id="vehicleDAO" class="geekzpacho.examples.ehcache.VehicleDAO"> </bean> </beans>Para comprobar la eficacia de ehcache y que todo sea correcto. Lanzamos en el Main.jav dos veces cada método dao (getAll y getVehicle), esperando que en la segunda llamada el tiempo de ejecución sea menor. Este es el resultado:
*** SELECT ALL *** First call without cache: 319246710 ns Vehicle [id=1, name=Car, description=Motor vehicle small or medium size, used for carrying people and can accommodate no more than nine seats.] Vehicle [id=2, name=MotorBike, description=Two-wheeled motor vehicle with one or two saddles and sometimes with sidecar.] Vehicle [id=3, name=Truck, description=Four or more vehicle wheels which is used to transport heavy loads.] Second call with cache: 597881 ns Vehicle [id=1, name=Car, description=Motor vehicle small or medium size, used for carrying people and can accommodate no more than nine seats.] Vehicle [id=2, name=MotorBike, description=Two-wheeled motor vehicle with one or two saddles and sometimes with sidecar.] Vehicle [id=3, name=Truck, description=Four or more vehicle wheels which is used to transport heavy loads.] ************** *** SELECT BY ID *** First call without cache: 57306107 ns Vehicle [id=1, name=Car, description=Motor vehicle small or medium size, used for carrying people and can accommodate no more than nine seats.] Second call with cache: 113113 ns Vehicle [id=1, name=Car, description=Motor vehicle small or medium size, used for carrying people and can accommodate no more than nine seats.] **************