隨着時間的積累,應用的使用用戶不斷增長,數據規模也愈來愈大,每每數據庫查詢操做會成爲影響用戶使用體驗的瓶頸,此時使用緩存每每是解決這一問題很是好的手段之一。Spring 3開始提供了強大的基於註解的緩存支持,能夠經過註解配置方式低侵入的給原有Spring應用增長緩存功能,提升數據訪問性能。html
Spring從3.1開始定義了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口來統一不一樣的緩存技術;同時支持JCache(JSR-107)註解。mysql
Cache | 緩存接口,定義緩存操做,實現有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 緩存管理器,管理各類緩存(Cache)組件 |
@Cacheable | 針對方法配置,根據方法的請求參數對其結果進行緩存 |
@CacheEvict | 清空緩存 |
@CachePut | 保證方法被調用,又但願結果被緩存 update,調用,將信息更新緩存 |
@EnableCaching | 開啓基於註解的緩存 |
KeyGenerator | 緩存數據時key生成的策略 |
serialize | 緩存數據時value序列化策略 |
一、新建一個SpringBoot1.5+web+mysql+mybatis+cacheweb
二、編寫配置文件,鏈接Mysqlredis
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.1.125:3306/test01 spring.datasource.username=root spring.datasource.password=root mybatis.configuration.map-underscore-to-camel-case=true server.port=9000
三、建立JaveBean實例spring
public class Employee { private Integer id; private String lastName; private String gender; private String email; private Integer dId; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getdId() { return dId; } public void setdId(Integer dId) { this.dId = dId; } @Override public String toString() { return "Employee{" + "id=" + id + ", lastName='" + lastName + '\'' + ", gender='" + gender + '\'' + ", email='" + email + '\'' + ", dId=" + dId + '}'; } }
四、建立mapper接口映射數據庫,並訪問數據庫中的數據sql
import com.wdjr.cache.bean.Employee; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; @Mapper public interface EmployeeMapper { @Select("SELECT * FROM employee WHERE id = #{id}") public Employee getEmpById(Integer id); @Update("UPDATE employee SET lastName=#{lastName},email=#{email},gender=#{gender},d_id=#{dId} WHERE id=#{id}") public void updateEmp(Employee employee); }
五、在pom.xml中引入cache依賴docker
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
六、主程序添加註解MapperScan,而且使用@EnableCaching,開啓緩存功能數據庫
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @EnableCaching @MapperScan("com.wdjr.cache.mapper") @SpringBootApplication public class Springboot01CacheApplication { public static void main(String[] args) { SpringApplication.run(Springboot01CacheApplication.class, args); } }
七、編寫service,來具體實現mapper中的方法,使用@Cacheable增長緩存apache
import com.wdjr.cache.bean.Employee; import com.wdjr.cache.mapper.EmployeeMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service public class EmployeeService { @Autowired EmployeeMapper employeeMapper; /** * 將方法的運行結果進行緩存,之後要是再有相同的數據,直接從緩存中獲取,不用調用方法 * CacheManager中管理多個Cache組件,對緩存的真正CRUD操做在Cache組件中,每一個緩存組件都有本身的惟一名字; * * 屬性: * CacheName/value:指定存儲緩存組件的名字 * key:緩存數據使用的key,可使用它來指定。默認是使用方法參數的值,或方法的返回值 * 編寫Spel表達式:#id 參數id的值, #a0/#p0 #root.args[0] * keyGenerator:key的生成器,本身能夠指定key的生成器的組件id * key/keyGendertor二選一使用 * * cacheManager指定Cache管理器,或者cacheReslover指定獲取解析器 * condition:指定符合條件的狀況下,才緩存; * unless:否認緩存,unless指定的條件爲true,方法的返回值就不會被緩存,能夠獲取到結果進行判斷 * sync:是否使用異步模式,unless不支持 * * */ @Cacheable(cacheNames = {"emp"},key = "#id",condition = "#id>0",unless = "#result==null") public Employee getEmp(Integer id){ System.out.println("查詢id= "+id+"的員工"); return employeeMapper.getEmpById(id); } }
八、編寫controller測試json
@RestController public class EmployeeController { @Autowired EmployeeService employeeService; @GetMapping("/emp/{id}") public Employee getEmp(@PathVariable("id")Integer id){ return employeeService.getEmp(id); } }
九、查看結果。具體結果就不截圖了,緩存功能開啓, 若是條件相同,只會查詢一次數據庫。
@CacheConfig
:主要用於配置該類中會用到的一些共用的緩存配置。在這裏@CacheConfig(cacheNames = "users")
:配置了該數據訪問對象中返回的內容將存儲於名爲users的緩存對象中,咱們也能夠不使用該註解,直接經過@Cacheable
本身配置緩存集的名字來定義。
@Cacheable
:配置了findByName函數的返回值將被加入緩存。同時在查詢時,會先從緩存中獲取,若不存在纔再發起對數據庫的訪問。該註解主要有下面幾個參數:
value
、cacheNames
:兩個等同的參數(cacheNames
爲Spring 4新增,做爲value
的別名),用於指定緩存存儲的集合名。因爲Spring 4中新增了@CacheConfig
,所以在Spring 3中本來必須有的value
屬性,也成爲非必需項了key
:緩存對象存儲在Map集合中的key值,非必需,缺省按照函數的全部參數組合做爲key值,若本身配置需使用SpEL表達式,好比:@Cacheable(key = "#p0")
:使用函數第一個參數做爲緩存的key值,更多關於SpEL表達式的詳細內容可參考官方文檔condition
:緩存對象的條件,非必需,也需使用SpEL表達式,只有知足表達式條件的內容纔會被緩存,好比:@Cacheable(key = "#p0", condition = "#p0.length() < 3")
,表示只有當第一個參數的長度小於3的時候纔會被緩存,若作此配置上面的AAA用戶就不會被緩存,讀者可自行實驗嘗試。unless
:另一個緩存條件參數,非必需,需使用SpEL表達式。它不一樣於condition
參數的地方在於它的判斷時機,該條件是在函數被調用以後才作判斷的,因此它能夠經過對result進行判斷。keyGenerator
:用於指定key生成器,非必需。若須要指定一個自定義的key生成器,咱們須要去實現org.springframework.cache.interceptor.KeyGenerator
接口,並使用該參數來指定。須要注意的是:該參數與key
是互斥的cacheManager
:用於指定使用哪一個緩存管理器,非必需。只有當有多個時才須要使用cacheResolver
:用於指定使用那個緩存解析器,非必需。需經過org.springframework.cache.interceptor.CacheResolver
接口來實現本身的緩存解析器,並用該參數指定。除了上面的兩個註解外,還有一些其餘的註解。
默認的緩存是在內存中定義HashMap,在實際的開發生產中,常用Redis做爲緩存中間件,而不使用cache。
Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它能夠用做數據庫、緩存和消息中間件。也是以key-value的形式進行存儲數據的一款非關係型數據庫。
步驟:
一、安裝Redis:將安裝redis在虛擬機中(docker)。 推薦去docker中國中去下載。
#拉取redis鏡像
docker pull redis
#啓動redis,並對外發開,使外部能夠鏈接到虛擬機中的rdeis
docker run -d -p 6379:6379 --name redis01 bfcb1f6df2db
安裝後可使用 Redis Desktop Manager管理工具去管理redis。
二、Redis的Tempate
Redis的經常使用五大數據類型
String【字符串】、List【列表】、Set【集合】、Hash【散列】、ZSet【有序集合】
分爲兩種一種是StringRedisTemplate,另外一種是RedisTemplate
根據不一樣的數據類型,大體的操做也分爲這5種,以StringRedisTemplate爲例
tringRedisTemplate.opsForValue() --String stringRedisTemplate.opsForList() --List stringRedisTemplate.opsForSet() --Set stringRedisTemplate.opsForHash() --Hash stringRedisTemplate.opsForZset() -Zset
a.導入Redis依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
b.修改配置文件
spring.redis.host=192.168.1.125
3.添加測試類
@Autowired StringRedisTemplate stringRedisTemplate;//操做字符串【經常使用】 @Autowired RedisTemplate redisTemplate;//操做k-v都是對象 @Test public void test01(){ // stringRedisTemplate.opsForValue().append("msg", "hello"); String msg = stringRedisTemplate.opsForValue().get("msg"); System.out.println(msg); }
咱們須要作的配置和測試到這裏就已經完成了。
而且Spring Boot會在偵測到存在Redis的依賴而且Redis的配置是可用的狀況下,還可使用RedisCacheManager初始化CacheManager。
三、保存對象
@Configuration public class MyRedisConfig { @Bean public RedisTemplate<Object, Employee> empRedisTemplate( RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate<Object, Employee>(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<Employee> jsonRedisSerializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class); template.setDefaultSerializer(jsonRedisSerializer); return template; }