SpringCache完整案例介绍

网友投稿 958 2022-05-30

Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager 接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化我们开发;Cache接口为缓存的组件规范定义,包含缓存的各种操作集合;Cache接口下Spring提供了各种xxxCache的实现;如RedisCache,EhCacheCache ,ConcurrentMapCache等;本文我们就来介绍下SpringCache的具体使用。

一、缓存中的重要概念

@Cacheable/@CachePut/@CacheEvict 主要的参数

二、SpEL上下文数据

Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档

注意:

SpringCache完整案例介绍

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。 如

@Cacheable(key = “targetClass + methodName +#p0”)

使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:

@Cacheable(value=“users”, key="#id")

@Cacheable(value=“users”, key="#p0")

三、SpringCache的使用

1.导入依赖

org.springframework.boot spring-boot-starter-cache

1

2

3

4

2.然后在启动类注解@EnableCaching开启缓存

3.创建业务类

package com.dpb.springboot.service; import com.dpb.springboot.pojo.User; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; /** * @program: springboot-13-cache * @description: * @author: 波波烤鸭 * @create: 2019-11-27 21:25 */ @Service public class UserService { /** * @Cacheable注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存 * 此处的User实体类一定要实现序列化public class User implements Serializable,否则会报java.io.NotSerializableException异常。 * @param userName * @return */ @Cacheable(value = "userCache" , key = "#userName") public User getUserByName(String userName){ System.out.println("数据库查询...." + userName); return getFromDB(userName); } /** * 清除一条记录 * @param user */ @CacheEvict(value = "userCache",key = "#user.name") public void updateUser(User user){ System.out.println("数据更新了。。。。数据库"); updateDB(user); } /** * allEntries:是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 * beforeInvocation:是否在方法执行前就清空,缺省为 false,如果指定为 true, * 则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 */ @CacheEvict(value = "userCache",allEntries = true,beforeInvocation = true) public void reload(){ // } private User getFromDB(String userName){ System.out.println("查询数据库..." + userName); return new User(666,userName); } private void updateDB(User user){ System.out.println("更新数据..." + user.getName()); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

4.创建缓存实现类

我们自定义一个基于内存的缓存实现 Cache接口,并实现相关的方法

package com.dpb.springboot.cache; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; /** * @program: springboot-13-cache * @description: * @author: 波波烤鸭 * @create: 2019-11-27 21:32 */ public class MyCache implements Cache { // 缓存的 key private String name; // 保存缓存数据的容器 private Map store = new ConcurrentHashMap<>(); public MyCache() { } public MyCache(String name) { this.name = name; } @Override public String getName() { return this.name; } public void setName(String name) { this.name = name; } /** * 返回数据容器 * @return */ @Override public Object getNativeCache() { return store; } /** * 返回缓存数据 * @param key * @return */ @Override public ValueWrapper get(Object key) { ValueWrapper result = null; Object thevalue = store.get(key); if(thevalue != null){ result = new SimpleValueWrapper(thevalue); System.out.println("执行了缓存查询...命中" + key); }else{ System.out.println("执行了缓存查询...没有命中" + key); } return result; } /** * 返回缓存数据 基于泛型 * @param key * @param aClass * @param * @return */ @Override public T get(Object key, Class aClass) { return aClass.cast(store.get(key)); } @Override public T get(Object o, Callable callable) { return null; } /** * 保存缓存数据 * @param o * @param o1 */ @Override public void put(Object o, Object o1) { // System.out.println("数据缓存了..." + o); store.put((String)o,o1); } /** * 清除一条缓存数据 * @param key */ @Override public void evict(Object key) { System.out.println("移走了元素:" + key); store.remove(key); } /** * 清空所有的数据 */ @Override public void clear() { store.clear(); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

5.配置缓存管理器

Spring的配置文件中如下配置

6.测试代码

package com.dpb.springboot; import com.dpb.springboot.pojo.User; import com.dpb.springboot.service.UserService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class Springboot13CacheApplicationTests { @Autowired private UserService service ; @Test void contextLoads() { System.out.println("第一次查询..."); service.getUserByName("hello"); System.out.println("第二次查询..."); service.getUserByName("hello"); System.out.println("*************"); // 更新记录 User user1 = service.getUserByName("user1"); // 开始更新其中一个 user1.setId(1111); service.updateUser(user1); // 更新后再查询 service.getUserByName("user1"); // 再次查询 service.getUserByName("user1"); // 更新所有 service.reload(); System.out.println("清空了所有的缓存..."); service.getUserByName("user1"); service.getUserByName("user2"); service.getUserByName("user1"); service.getUserByName("user2"); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

测试结果

第一次查询... 执行了缓存查询...没有命中hello 数据库查询....hello 查询数据库...hello 数据缓存了...hello 第二次查询... 执行了缓存查询...命中hello ************* 执行了缓存查询...没有命中user1 数据库查询....user1 查询数据库...user1 数据缓存了...user1 数据更新了。。。。数据库 更新数据...user1 移走了元素:user1 执行了缓存查询...没有命中user1 数据库查询....user1 查询数据库...user1 数据缓存了...user1 执行了缓存查询...命中user1 清空了所有的缓存... 执行了缓存查询...没有命中user1 数据库查询....user1 查询数据库...user1 数据缓存了...user1 执行了缓存查询...没有命中user2 数据库查询....user2 查询数据库...user2 数据缓存了...user2 执行了缓存查询...命中user1 执行了缓存查询...命中user2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

搞定~

Spring 数据库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:excel表格中不同部门的员工如何快速输入编号
下一篇:企业级应用 API 开发方法大全
相关文章