Spring Boot的数据访问(四)Cache与Redis

缓存(Cache)

简介

当我们需要重复地获取相同的数据的时候,我们一次又一次的请求数据库或者远程服务,导致大量的时间耗费在数据库查询或者远程方法的调用上,导致程序性能的恶化,这便是缓存要解决的问题。

实战

1:新建Spring Boot项目,添加依赖JPA、Web和Cache,并导入数据库驱动
2:配置属性
application.properties

//数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/book
spring.datasource.username=root
spring.datasource.password=123456

//JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent-output=true

实体类Person

@Entity
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;
	}
}

实体类Repository

public interface PersonRepository extends JpaRepository<Person, Long> {

}

服务接口

public interface DemoService {
	public Person save(Person person);
	
	public void remove(Long id);
	
	public Person findOne(Person person);

}

服务接口的实现

@Service
public class DemoServiceImpl implements DemoService {
	
	@Autowired
	PersonRepository personRepository;

	@Override
	//@CachePut缓存新增的或更新的数据到缓存,其中缓存名称为people,数据的key是person的id
	@CachePut(value = "people", key = "#person.id")
	public Person save(Person person) {
		Person p = personRepository.save(person);
		System.out.println("为id、key为:"+p.getId()+"数据做了缓存");
		return p;
	}

	@Override
	//@CacheEvict从缓存people中删除key为id的数据
	@CacheEvict(value = "people")
	public void remove(Long id) {
		System.out.println("删除了id、key为"+id+"的数据缓存");
		//这里不做实际删除操作
	}

	@Override
	//@Cacheable缓存key为person的id数据到缓存people中,如果没有指定key,则方法参数作为key保存到缓存中
	@Cacheable(value = "people", key = "#person.id")
	public Person findOne(Person person) {
		Person p = personRepository.findOne(person.getId());
		System.out.println("为id、key为:"+p.getId()+"数据做了缓存");
		return p;
	}

}

控制器CacheController

@RestController
public 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";
		
	}
}

AppConfig.java

@Configuration
@EnableCaching  //Spring Boot中还是要使用@EnableCaching 开启缓存支持
public class AppConfig {

}

运行测试:

测试@Cacheable:
这里写图片描述
这里写图片描述
再次访问,此时控制台不会再次输入Hibernate的查询语句,以及“为id、key为:1数据做了缓存”字样。表示没有调用这个方法,页面直接从数据缓存中获得数据;

测试@CachePut(@CachePut注解的方法总是会被执行)
控制台输出如下:
这里写图片描述
这里写图片描述
再次访问,控制台仍会输出:
这里写图片描述

测试@CacheEvit:
从缓存中删除key为1的缓存数据:
这里写图片描述
再次访问:
这里写图片描述
这里写图片描述

切换缓存技术

Redis
只需添加下面依赖即可:

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

非关系型数据库NoSQL

Redis

实战

1:新建Spring Boot项目,添加依赖Redis和Web,并导入数据库驱动
2:配置属性(Spring Boot默认数据库连接满足我们当前测试要求,所以无需在application.properties配置连接信息)
3:领域模型类

public class Person implements Serializable{

	private static final long serialVersionUID = 1L;
	
	private String id;
	private String name;
	private Integer age;
	
	public Person() {
		super();//使用Jackson做序列化需要一个空构造
	}
	public Person(String id,String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String 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;
	}
}

4:数据访问

@Repository
public class PersonDao {
	
	@Autowired
	StringRedisTemplate stringRedisTemplate; //注入StringRedisTemplate
	
	@Resource(name="stringRedisTemplate")
	ValueOperations<String,String> valOpsStr; //使用@Resource注解指定stringRedisTemplate,可注入基于字符串的简单属性操作方法
	
	
	@Autowired
	RedisTemplate<Object, Object> redisTemplate; //注入RedisTemplate
	
	@Resource(name="redisTemplate")
	ValueOperations<Object, Object> valOps; ////使用@Resource注解指定redisTemplate,可注入基于对象的简单属性操作方法
	
	public void stringRedisTemplateDemo(){ //set方法,存储字符串类型
		valOpsStr.set("xx", "yy");
	}
	
	
	public void save(Person person){ //set方法,存储对象类型
		valOps.set(person.getId(),person);
	}
	
	public String getString(){//get方法,获取字符串
		return valOpsStr.get("xx");
	}
	
	public Person getPerson(){//get方法,获取对象
		return (Person) valOps.get("1");
	}

}

控制器DataController

@RestController
public class DataController {
	
	@Autowired
	PersonDao personDao;
	
	@RequestMapping("/set") //设置字符及对象
	public void set(){
		Person person = new Person("1","wyf", 32);
		personDao.save(person);
		personDao.stringRedisTemplateDemo();
	}
	
	@RequestMapping("/getStr") //获得字符
	public String getStr(){
		return personDao.getString();
	}
	
	@RequestMapping("/getPerson") //获得对象
	public Person getPerson(){
		return personDao.getPerson();
	}
}

运行测试:
这里写图片描述
这里写图片描述
这里写图片描述

参考书籍:Spring Boot实战
以上只是学习所做的笔记,以供日后参考!!!

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/81128561