在Spring Boot中使用数据缓存
来源:互联网 发布:短信王软件 编辑:程序博客网 时间:2024/06/06 04:39
春节就要到了,在回家之前要赶快把今年欠下的技术债还清。so,今天继续。spring Boot前面已经预热了n篇博客了,今天我们来继续看如何在Spring Boot中解决数据缓存问题。本篇博客是以初识在Spring Boot中使用JPA为基础的,先了解如何实现数据访问,然后才好实现数据缓存。OK,对于Spring Boot尚有疑问的小伙伴可以先移步这里从SpringMVC到Spring Boot,老司机请略过。
OK,废话不多说,开始今天的技术之旅吧。
在实际开发中,对于要反复读写的数据,最好的处理方式是将之在内存中缓存一份,频繁的数据库访问会造成程序效率低下,同时内存的读写速度本身就要强于硬盘。Spring在这一方面给我们提供了诸多的处理手段,而Spring Boot又将这些处理方式进一步简化,接下来我们就来看看如何在Spring Boot中解决数据缓存问题。
创建Project并添加数据库驱动
Spring Boot的创建方式还是和我们前文提到的创建方式一样,不同的是这里选择添加的依赖不同,这里我们添加Web、Cache和JPA依赖,如下图:
创建成功之后,接下来添加数据库驱动,我还是使用MySQL,在pom.xml中添加数据库驱动,如下:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
配置application.properties
这个application.properties的配置还是和初识在Spring Boot中使用JPA一样,各个参数的含义我这里也不再赘述,我们直接来看代码:
spring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/sang?useUnicode=true&characterEncoding=utf-8spring.datasource.username=rootspring.datasource.password=sangspring.jpa.hibernate.ddl-auto=updatespring.jpa.show-sql=truespring.jackson.serialization.indent_output=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
创建实体类
@Entitypublic class Person { @Id @GeneratedValue private Long id; private String name; private String address; private Integer age; public Person() { } 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 String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Person(Long id, String name, String address, Integer age) { this.id = id; this.name = name; this.address = address; this.age = age; }}
- 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
- 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
创建实体类的Repository
public interface PersonRepository extends JpaRepository<Person,Long> {}
- 1
- 2
- 1
- 2
创建业务类
业务接口
public interface DemoService { public Person save(Person person); public void remove(Long id); public Person findOne(Person person);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
实现类
@Servicepublic class DemoServiceImpl implements DemoService { @Autowired PersonRepository personRepository; @CachePut(value = "people", key = "#person.id") @Override public Person save(Person person) { Person p = personRepository.save(person); System.out.println("为id、key为" + p.getId() + "数据做了缓存"); return p; } @CacheEvict(value = "people") @Override public void remove(Long id) { System.out.println("删除了id、key为" + id + "的数据缓存"); personRepository.delete(id); } @Cacheable(value = "people", key = "#person.id") @Override public Person findOne(Person person) { Person p = personRepository.findOne(person.getId()); System.out.println("为id、key为" + p.getId() + "数据做了缓存"); return p; }}@Servicepublic class DemoServiceImpl implements DemoService { @Autowired PersonRepository personRepository; @CachePut(value = "people", key = "#person.id") @Override public Person save(Person person) { Person p = personRepository.save(person); System.out.println("为id、key为" + p.getId() + "数据做了缓存"); return p; } @CacheEvict(value = "people") @Override public void remove(Long id) { System.out.println("删除了id、key为" + id + "的数据缓存"); personRepository.delete(id); } @Cacheable(value = "people", key = "#person.id") @Override public Person findOne(Person person) { Person p = personRepository.findOne(person.getId()); System.out.println("为id、key为" + p.getId() + "数据做了缓存"); return p; }}
- 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
- 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
关于这个实现类我说如下几点:
1.@CachePut表示缓存新添加的数据或者更新的数据到缓存中,两个参数value表示缓存的名称为people,key表示缓存的key为person的id
2.@CacheEvict表示从缓存people中删除key为id的数据
3.@Cacheable表示添加数据到缓存中,缓存名称为people,缓存key为person的id属性。
创建Controller
@RestControllerpublic class CacheController { @Autowired DemoService demoService; @RequestMapping("/put") public Person put(Person person) { return demoService.save(person); } @RequestMapping("/able") public Person cacheable(Person person) { return demoService.findOne(person); } @RequestMapping("/evit") public String evit(Long id) { demoService.remove(id); return "ok"; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
OK ,做完这一切我们就可以来测试我们刚刚写的缓存了。
测试
看我们的Controller,我们有三个地址要测试,一个一个来。当然,在 测试之前,我们先来看看初始状态下的数据库是什么样子的:
首先我们在浏览器中访问http://localhost:8080/able?id=1
,得到如下访问结果:
这个时候查看控制台,输出内容如下:
说是数据已经被缓存了,这个时候我们再继续在浏览器中刷新继续请求id为1的数据,会发现控制台不会继续打印日志出来,就是因为数据已被存于缓存之中了。
接下来我们向浏览器中输入http://localhost:8080/put?age=47&name=奥巴牛&address=米国
,访问结果如下:
这个时候查看控制台打印的日志如下:
再查看数据表,数据已插入成功:
此时,我们在浏览器中输入http://localhost:8080/able?id=106
,访问刚刚插入的这条数据,结果如下:
这个时候查看控制台,发现并没有数据数据,就是因为数据已经处于缓存中了。
最后我们在浏览器中输入http://localhost:8080/evit?id=106
,将数据从缓存中移除,访问结果如下:
这个时候查看控制台,已经提示缓存移除掉了:
同时数据也从数据库删除掉了,这个时候如果还需要该数据则需要我们继续向表中添加数据。
缓存技术切换
Spring Boot默认情况下使用ConcurrentMapCacheManager作为缓存技术,有的时候你可能想替换为其他的缓存方式,在Spring Boot中进行缓存的切换非常简单,我这里以Google提供的Guava为例,如果要使用这种缓存策略,只需要添加相应的依赖即可,如下:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>20.0</version></dependency>
就这样就可以了。实际上在Spring Boot中,底层使用哪一种缓存我们并不必做过多考虑,切换的方式也很简单,如上文引入相应的依赖即可,我们只需要把上层的逻辑写好即可。
本文案例下载:
本文GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test25-Cache.
更多Spring Boot案例请移步这里从SpringMVC到Spring Boot
- 在Spring Boot中使用数据缓存
- 在Spring Boot中使用数据缓存
- 在Spring Boot中使用数据缓存
- Spring Boot使用redis做数据缓存
- Spring Boot使用redis做数据缓存
- Spring Boot使用redis做数据缓存
- Spring Boot使用redis实现数据缓存
- Spring Boot使用redis做数据缓存
- Spring Boot使用redis做数据缓存
- Spring Boot使用redis做数据缓存
- spring boot使用redis做数据缓存
- Spring Boot使用redis做数据缓存
- Spring boot 中缓存的使用
- Spring Boot Redis 数据缓存
- Spring Boot 数据缓存 Cache
- Spring Boot:在Spring Boot中使用Mysql和JPA
- Spring Boot:在Spring Boot中使用定时任务
- Spring Boot:在Spring Boot中使用定时任务
- Hello Machine Learning
- hdu 2175 汉诺塔IX(找规律)
- Syntax error or access violation: 1286 Unknown storage engine 'InnoDB' 解决办法
- System.out与System.err
- 日期类
- 在Spring Boot中使用数据缓存
- sdutacm-数据结构实验之二叉树一:树的同构
- JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)
- [PHP 作为iOS后台Json格式HTTP通信及文件上传的实现]
- JSP九大内置对象及请求转发和重定向
- 游戏在手机上如何显示Log
- angular2采用自定义指令(Directive)方式加载jquery插件
- PAT A1127. ZigZagging on a Tree (30)
- PHP返回的json,Obj-C解析的一个例子