Browse Source

使用 redis 做缓存,demo 完成

v-1.5.x
yangkai.shen 7 years ago
parent
commit
49a57b3fae
12 changed files with 476 additions and 2 deletions
  1. +23
    -2
      README.md
  2. +172
    -0
      spring-boot-demo-cache-redis/README.md
  3. +31
    -0
      spring-boot-demo-cache-redis/pom.xml
  4. +14
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/SpringBootDemoCacheRedisApplication.java
  5. +61
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/controller/UserController.java
  6. +71
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/dao/UserDao.java
  7. +14
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/entity/User.java
  8. +19
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/service/UserService.java
  9. +47
    -0
      spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/service/impl/UserServiceImpl.java
  10. +7
    -0
      spring-boot-demo-cache-redis/src/main/resources/application.yml
  11. +16
    -0
      spring-boot-demo-cache-redis/src/test/java/com/xkcoding/springbootdemocacheredis/SpringBootDemoCacheRedisApplicationTests.java
  12. +1
    -0
      spring-boot-demo-parent/pom.xml

+ 23
- 2
README.md View File

@@ -1,6 +1,6 @@
# Spring Boot Demo

spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuator、logback、mybatis 模块,后续会集成activemq,redis,email, freemarker,shiro,websocket,sitemesh,ehcache,easyui,kindeditor,quartz,springfox,swagger,jpa,hibernate,querydsl,netty等模块。
spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuator、logback、jpa、mybatis、redis缓存 模块,后续会集成activemq,email, freemarker,shiro,websocket,quartz,springfox,swagger,netty等模块。

依赖的 Spring Boot 版本:

@@ -40,6 +40,7 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato
<module>../spring-boot-demo-logback</module>
<module>../spring-boot-demo-jpa</module>
<module>../spring-boot-demo-mybatis</module>
<module>../spring-boot-demo-cache-redis</module>
</modules>

<parent>
@@ -53,6 +54,10 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<hutool.version>3.2.0</hutool.version>
<commons.lang3.version>3.5</commons.lang3.version>
<commons.collections.version>3.2.2</commons.collections.version>
<commons.codec.version>1.10</commons.codec.version>
</properties>

<dependencies>
@@ -76,9 +81,24 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato
</dependency>
<!--工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons.lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons.collections.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons.codec.version}</version>
</dependency>
<dependency>
<groupId>com.xiaoleilu</groupId>
<artifactId>hutool-all</artifactId>
<version>3.1.2</version>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
@@ -113,6 +133,7 @@ spring boot demo 一个用来学习 spring boot 的项目,已经集成 actuato
| [spring-boot-demo-logback](./spring-boot-demo-logback) | spring-boot 集成 logback 日志 |
| [spring-boot-demo-jpa](./spring-boot-demo-jpa) | spring-boot 集成 spring-boot-starter-data-jpa 操作数据库 |
| [spring-boot-demo-mybatis](./spring-boot-demo-mybatis) | spring-boot 集成 [mybatis-spring-boot-starter](https://github.com/mybatis/spring-boot-starter)、[mybatis-spring-boot-starter](https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter) |
| [spring-boot-demo-cache-redis](./spring-boot-demo-cache-redis) | spring-boot 使用 Redis 做缓存 |

# 官方提供的 starter 介绍



+ 172
- 0
spring-boot-demo-cache-redis/README.md View File

@@ -0,0 +1,172 @@
# spring-boot-demo-cache-redis

依赖 [spring-boot-demo-parent](../spring-boot-demo-parent)、`spring-boot-starter-data-redis`

### pom.xml

```xml
<?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>

<artifactId>spring-boot-demo-cache-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>spring-boot-demo-cache-redis</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>com.xkcoding</groupId>
<artifactId>spring-boot-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>

<build>
<finalName>spring-boot-demo-cache-redis</finalName>
</build>

</project>
```

### application.yml

```yml
server:
port: 8080
context-path: /demo
spring:
redis:
host: localhost
port: 6379
```

### SpringBootDemoCacheRedisApplication.java (开启使用缓存注解)

```java
@SpringBootApplication
@EnableCaching
public class SpringBootDemoCacheRedisApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args);
}
}
```

### User.java (一定要序列化!)

```java
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1442134563392432775L;
private Long id;
private String name;
private Date birthDay;
}
```

### UserController.java

```java
@RestController
@RequestMapping("/user")
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称
public class UserController {

@Autowired
private UserService userService;

@GetMapping({"", "/"})
@Cacheable
public List<User> index() {
return userService.find();
}

@GetMapping("/find/{id}")
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法
public User find(@PathVariable Long id) {
return userService.find(id);
}

@GetMapping("/find")
@Cacheable(key = "#name", condition = "#name != null")
public User find(@RequestParam String name) {
return userService.find(name);
}

@GetMapping("/save")
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存
public User save() {
return userService.save();
}

@GetMapping("/update/{id}")
@CacheEvict(allEntries = true, beforeInvocation = true)
public User update(@PathVariable Long id) {
return userService.update(id);
}

@GetMapping("/delete/{id}")
@CacheEvict(allEntries = true, beforeInvocation = true)
public String delete(@PathVariable Long id) {
User user = userService.delete(id);
if (user == null) {
return "用户不存在";
} else {
return user.getName() + "删除成功";
}
}
}
```

### 其余 Service、Dao 代码(采用 List 存储,只为了演示启用 cache 后,是否仍会进入对应的 method)

详情请参见本demo。

### 缓存 @Annotation 详解

#### @CacheConfig

用于统一配置缓存的基本信息

#### @Cacheable

将返回的结果缓存,该注解里的参数如下

| 参数 | 作用 | 示例 |
| --------- | ---------------------------------------- | ---------------------------------------- |
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) |

#### @CacheEvict

能够根据一定的条件对缓存进行清空,该注解里的参数如下

| 参数 | 作用 | 示例 |
| ---------------- | ---------------------------------------- | ---------------------------------------- |
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@CachEvict(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如:@CachEvict(value=”testcache”,condition=”#userName.length()>2”) |
| allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如:@CachEvict(value=”testcache”,allEntries=true) |
| beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如:@CachEvict(value=”testcache”,beforeInvocation=true) |

#### @CachePut

能够根据方法的请求参数对其结果进行缓存,和 `@Cacheable` 不同的是,它每次都会触发真实方法的调用

| 参数 | 作用 | 示例 |
| --------- | ---------------------------------------- | ---------------------------------------- |
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如:@Cacheable(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”) |

+ 31
- 0
spring-boot-demo-cache-redis/pom.xml View File

@@ -0,0 +1,31 @@
<?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>

<artifactId>spring-boot-demo-cache-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>spring-boot-demo-cache-redis</name>
<description>Demo project for Spring Boot</description>

<parent>
<groupId>com.xkcoding</groupId>
<artifactId>spring-boot-demo-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../spring-boot-demo-parent/pom.xml</relativePath>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies>

<build>
<finalName>spring-boot-demo-cache-redis</finalName>
</build>

</project>

+ 14
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/SpringBootDemoCacheRedisApplication.java View File

@@ -0,0 +1,14 @@
package com.xkcoding.springbootdemocacheredis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class SpringBootDemoCacheRedisApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootDemoCacheRedisApplication.class, args);
}
}

+ 61
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/controller/UserController.java View File

@@ -0,0 +1,61 @@
package com.xkcoding.springbootdemocacheredis.controller;

import com.xkcoding.springbootdemocacheredis.entity.User;
import com.xkcoding.springbootdemocacheredis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
@CacheConfig(cacheNames = "users") // 整体配置缓存的名称
public class UserController {

@Autowired
private UserService userService;

@GetMapping({"", "/"})
@Cacheable
public List<User> index() {
return userService.find();
}

@GetMapping("/find/{id}")
@Cacheable(key = "#id", condition = "#id != null") // #id 以及 condition 里的语法是 SpEL 语法
public User find(@PathVariable Long id) {
return userService.find(id);
}

@GetMapping("/find")
@Cacheable(key = "#name", condition = "#name != null")
public User find(@RequestParam String name) {
return userService.find(name);
}

@GetMapping("/save")
@CacheEvict(allEntries = true, beforeInvocation = true) //@CacheEvict 清空缓存
public User save() {
return userService.save();
}

@GetMapping("/update/{id}")
@CacheEvict(allEntries = true, beforeInvocation = true)
public User update(@PathVariable Long id) {
return userService.update(id);
}

@GetMapping("/delete/{id}")
@CacheEvict(allEntries = true, beforeInvocation = true)
public String delete(@PathVariable Long id) {
User user = userService.delete(id);
if (user == null) {
return "用户不存在";
} else {
return user.getName() + "删除成功";
}
}
}

+ 71
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/dao/UserDao.java View File

@@ -0,0 +1,71 @@
package com.xkcoding.springbootdemocacheredis.dao;

import com.google.common.collect.Lists;
import com.xkcoding.springbootdemocacheredis.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Component
public class UserDao {
private static List<User> users = Lists.newArrayList();
private static AtomicLong SEQ = new AtomicLong(0L);

public User save() {
log.info("save.....");
User user = new User();
user.setId(SEQ.get());
user.setName("xkcoding" + SEQ.get());
user.setBirthDay(new Date());
users.add(user);
SEQ.getAndIncrement();
return user;
}

public User update(Long id) {
log.info("update.....");
for (User user1 : users) {
if (user1.getId().equals(id)) {
user1.setName("修改后的名字");
return user1;
}
}
return null;
}

public User delete(Long id) {
log.info("delete.....");
User user = find(id);
users.remove(user);
return user;
}

public List<User> find() {
log.info("findAll.....");
return users;
}

public User find(String name) {
log.info("findByName.....");
for (User user : users) {
if (user.getName().equals(name)) {
return user;
}
}
return null;
}

public User find(Long id) {
log.info("findById.....");
for (User user : users) {
if (user.getId().equals(id)) {
return user;
}
}
return null;
}
}

+ 14
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/entity/User.java View File

@@ -0,0 +1,14 @@
package com.xkcoding.springbootdemocacheredis.entity;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
public class User implements Serializable {
private static final long serialVersionUID = 1442134563392432775L;
private Long id;
private String name;
private Date birthDay;
}

+ 19
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/service/UserService.java View File

@@ -0,0 +1,19 @@
package com.xkcoding.springbootdemocacheredis.service;

import com.xkcoding.springbootdemocacheredis.entity.User;

import java.util.List;

public interface UserService {
User save();

User update(Long id);

User delete(Long id);

List<User> find();

User find(Long id);

User find(String name);
}

+ 47
- 0
spring-boot-demo-cache-redis/src/main/java/com/xkcoding/springbootdemocacheredis/service/impl/UserServiceImpl.java View File

@@ -0,0 +1,47 @@
package com.xkcoding.springbootdemocacheredis.service.impl;

import com.xkcoding.springbootdemocacheredis.dao.UserDao;
import com.xkcoding.springbootdemocacheredis.entity.User;
import com.xkcoding.springbootdemocacheredis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;

@Override
public User save() {
return userDao.save();
}

@Override
public User update(Long id) {
return userDao.update(id);
}

@Override
public User delete(Long id) {
return userDao.delete(id);
}

@Override
public List<User> find() {
return userDao.find();
}

@Override
public User find(Long id) {
return userDao.find(id);
}

@Override
public User find(String name) {
return userDao.find(name);
}
}

+ 7
- 0
spring-boot-demo-cache-redis/src/main/resources/application.yml View File

@@ -0,0 +1,7 @@
server:
port: 8080
context-path: /demo
spring:
redis:
host: localhost
port: 6379

+ 16
- 0
spring-boot-demo-cache-redis/src/test/java/com/xkcoding/springbootdemocacheredis/SpringBootDemoCacheRedisApplicationTests.java View File

@@ -0,0 +1,16 @@
package com.xkcoding.springbootdemocacheredis;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDemoCacheRedisApplicationTests {

@Test
public void contextLoads() {
}

}

+ 1
- 0
spring-boot-demo-parent/pom.xml View File

@@ -18,6 +18,7 @@
<module>../spring-boot-demo-logback</module>
<module>../spring-boot-demo-jpa</module>
<module>../spring-boot-demo-mybatis</module>
<module>../spring-boot-demo-cache-redis</module>
</modules>

<parent>


Loading…
Cancel
Save