Introduction
Our knowledge is that the bottleneck of a program lies in the database, and our knowledge also knows that the speed of memory is much faster than that of the hard disk. When our department needs to obtain the same data repeatedly, our department requests the database or remote service again and again, resulting in a lot of time spent on database query or remote method calls, resulting in deterioration in program performance, which is even more a problem that data cache needs to solve.
spring caching support
spring defines the org.springframework.cache.CacheManager and org.springframework.cache.Cache interfaces to unify different caching technologies. Among them, CacheManager is an abstract interface for various cache technology provided by Spring. The Cache interface includes various cache operations (adding and deleting to obtain cache, our system generally does not directly deal with this interface)
CacheManager supported by spring
For different caching technologies, different CacheManagers need to be implemented. Spring defines the CacheManager implementation in the following table.
When implementing any CacheManager, you need to register a bean that implements CacheManager. Of course, each caching technology has many additional configurations, but configuring CacheManager is essential.
Declarative cache annotation
spring provides 4 annotations to declare cache rules (a vivid example of AOP using annotated formulas), as shown in the table.
Turn on declarative cache
Turning on declarative caching support is very simple, you only need to use the @EnabelCaching annotation on the configuration class.
Support for springBoot
The key to using cache technology in spring China is to configure CacheManager. Springbok automatically configures multiple CacheManager implementations for our door. In the spring boot environment, using cache technology only requires importing the dependency packages of related cache technology in the project and configuring the class to enable cache support using @EnabelCaching.
Small examples
A small example is implemented using springboot+jpa+cache.
Example Steps Directory
1. Create a maven project
Create a new maven project pom.xml file as follows:
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.us</groupId> <artifactId>springboot-Cache</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.0.RELEASE</version> </parent> <properties> <start-class>com.us.Application</start-class> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties> <!-- Add typical dependencies for a web application --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency> <!--db--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> </dependencies></project>
2. Database configuration
Create a new application.properties file in the src/main/esouches directory, and the content is database connection information, as follows:
application.properties
ms.db.driverClassName=com.mysql.jdbc.Driverms.db.url=jdbc:mysql://localhost:3306/cache?prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=truems.db.username=rootms.db.password=xxxxxxms.db.maxActive=500
Create a new DBConfig.java configuration file and configure the data source
package com.us.example.config;/** * Created by yangyibo on 17/1/13. */import java.beans.PropertyVetoException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import com.mchange.v2.c3p0.ComboPooledDataSource;@Configurationpublic class DBConfig { @Autowired private Environment env; @Bean(name="dataSource") public ComboPooledDataSource dataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(env.getProperty("ms.db.driverClassName")); dataSource.setJdbcUrl(env.getProperty("ms.db.url")); dataSource.setUser(env.getProperty("ms.db.username")); dataSource.setPassword(env.getProperty("ms.db.password")); dataSource.setMaxPoolSize(20); dataSource.setMinPoolSize(5); dataSource.setInitialPoolSize(10); dataSource.setMaxIdleTime(300); dataSource.setAcquireIncrement(5); dataSource.setIdleConnectionTestPeriod(60); return dataSource; }}Database design, the database has only one Person table, and the design is as follows:
3.jpa configuration
The spring-data-jpa configuration file is as follows:
package com.us.example.config;import java.util.HashMap;import java.util.Map;import javax.persistence.EntityManagerFactory;import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.jpa.repository.config.EnableJpaRepositories;import org.springframework.orm.jpa.JpaTransactionManager;import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;import org.springframework.transaction.PlatformTransactionManager;import org.springframework.transaction.annotation.EnableTransactionManagement;/** * Created by yangyibo on 17/1/13. */@Configuration@EnableJpaRepositories("com.us.example.dao")@EnableTransactionManagement@ComponentScanpublic class JpaConfig { @Autowired private DataSource dataSource; @Bean public EntityManagerFactory entityManagerFactory() { HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.us.example.bean"); factory.setDataSource(dataSource); Map<String, Object> jpaProperties = new HashMap<>(); jpaProperties.put("hibernate.ejb.naming_strategy","org.hibernate.cfg.ImprovedNamingStrategy"); jpaProperties.put("hibernate.jdbc.batch_size",50); factory.setJpaPropertyMap(jpaProperties); factory.afterPropertiesSet(); return factory.getObject(); } @Bean public PlatformTransactionManager transactionManager() { JpaTransactionManager txManager = new JpaTransactionManager(); txManager.setEntityManagerFactory(entityManagerFactory()); return txManager; }}4. Write beans and dao layers
Entity class Person.java
package com.us.example.bean;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;/** * Created by yangyibo on 17/1/13. */@Entity@Table(name = "Person")public class Person { @Id @GeneratedValue private Long id; private String name; private Integer age; private String address; public Person() { super(); } public Person(Long id, String name, Integer age, String address) { super(); this.id = id; this.name = name; this.age = age; this.address = address; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; }}dao layer, PersonRepository.java
package com.us.example.dao;import com.us.example.bean.Person;import org.springframework.data.jpa.repository.JpaRepository;/** * Created by yangyibo on 17/1/13. */public interface PersonRepository extends JpaRepository<Person, Long> {}5. Write the service layer
service interface
package com.us.example.service;import com.us.example.bean.Person;/** * Created by yangyibo on 17/1/13. */public interface DemoService { public Person save(Person person); public void remove(Long id); public Person findOne(Person person);}Implementation: (key, add cache here)
package com.us.example.service.Impl;import com.us.example.bean.Person;import com.us.example.dao.PersonRepository;import com.us.example.service.DemoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;/** * Created by yangyibo on 17/1/13. */@Servicepublic class DemoServiceImpl implements DemoService { @Autowired private PersonRepository personRepository; @Override //@CachePut caches newly added or updated data to the cache, where the cache name is people. The key of the data is the id of person @CachePut(value = "people", key = "#person.id") public Person save(Person person) { Person p = personRepository.save(person); System.out.println("For id, key is:"+p.getId()+"Data cached"); return p; } @Override //@CacheEvict Remove data with key id from cache people @CacheEvict(value = "people") public void remove(Long id) { System.out.println("Deleted the data cache with id and key "+id+"); //The actual deletion operation is not performed here} @Override //@Cacheable caches the id data with the key person in the cache people. If no key is specified, the method parameters are saved to the cache as key. @Cacheable(value = "people", key = "#person.id") public Person findOne(Person person) { Person p = personRepository.findOne(person.getId()); System.out.println("For id, key is:"+p.getId()+"Data cached"); return p; }}6. Write controller
For the convenience of testing, get is used
package com.us.example.controller;import com.us.example.bean.Person;import com.us.example.service.DemoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;/** * Created by yangyibo on 17/1/13. */@RestControllerpublic class CacheController { @Autowired private DemoService demoService; //http://localhost:8080/put?name=abel&age=23&address=shanghai @RequestMapping("/put") public Person put(Person person){ return demoService.save(person); } //http://localhost:8080/able?id=1 @RequestMapping("/able") @ResponseBody public Person cacheable(Person person){ return demoService.findOne(person); } //http://localhost:8080/evit?id=1 @RequestMapping("/evit") public String evit(Long id){ demoService.remove(id); return "ok"; }}7. Start cache
Remember to enable cache configuration in the startup class.
package com.us.example;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;import static org.springframework.boot.SpringApplication.*;/** * Created by yangyibo on 17/1/13. */@ComponentScan(basePackages ="com.us.example")@SpringBootApplication@EnableCachingpublic class Application { public static void main(String[] args) { ConfigurableApplicationContext run = run(Application.class, args); }}8. Test verification and verification ability:
Start the Application class, and after starting it, enter: http://localhost:8080/able?id=1 in the browser (first to initialize several pieces of data in the database.)
Console output:
"The data of id and key is:1" has been cached for this query. If you query the data again, this statement will not appear, that is, the database will not be queried.
Inspection put
Enter in the browser: http://localhost:8080/put?name=abel&age=23&address=shanghai (Insert a data into the database and put the data into the cache.)
At this time, the console output caches the record:
Then call the able method again to query the data. The database will no longer be queried, and the data will be read directly from the cache.
Test Evit
Enter: http://localhost:8080/evit?id=1 in the browser (clear the record from the cache, after clearing it, the record will be put into the cache again after accessing the record.)
Console output:
Switch cache
1. Switch to EhCache as cache
Add dependencies in the pom.xml file
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
Create the configuration file ehcache.xml in the resource folder. The contents of the new ehcache configuration file are as follows. This file spring boot will automatically scan
<?xml version="1.0" encoding="UTF-8"?><ehcache> <!--Used when switching to ehcache cache --><cache name="people" maxElementsInMemory="1000" /></ehcache>
2. Switch to Guava as cache
Just add dependencies in the pom
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>18.0</version> </dependency>
3. Switch to redis as cache
Please read the next blog
Reference for this article: "The Disruptor of JavaEE Development: Spring Boot Practical Battle"
Source code of this article: https://github.com/527515025/springBoot.git
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.