Spring Boot 缓存Ehcache、Redis(六)

Spring Boot 缓存技术

一、Spring Boot整合Ehcache

如果对Ehcache不了解可以查看一下文档,进行了解

1 修改 pom 文件

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>

		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.10.RELEASE</version>
	</parent>
	<groupId>com.xk</groupId>
	<artifactId>spring-boot-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<java.version>1.7</java.version>
		<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
		<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
	</properties>

	<dependencies>
		<!-- springBoot 的启动器 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- thymeleaf 的启动器 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<!-- springBoot 的启动器 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<!-- 测试工具的启动器 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<!-- druid 连接池 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.9</version>
		</dependency>
		<!-- Spring Boot 缓存支持启动器 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<!-- Ehcache  -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
		</dependency>
	</dependencies>

</project>

2、创建 Ehcache 的配置文件

文件名:ehcache.xml
位置:src/main/resources/ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
	<diskStore path="java.io.tmpdir" />
	<!--defaultCache:echcache的默认缓存策略 -->
	<defaultCache maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120"
		maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
		<persistence strategy="localTempSwap" />
	</defaultCache>
	<!-- 自定义缓存策略 -->
	<cache name="users" maxElementsInMemory="10000" eternal="false"
		timeToIdleSeconds="120" timeToLiveSeconds="120"
		maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU">
		<persistence strategy="localTempSwap" />
	</cache>
</ehcache>

3、修改 application.properties 文件

spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.username=root
spring.datasource.password=root

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

spring.cache.ehcache.cofnig=ehcache.xml

4 修改启动类

@EnableCaching
@SpringBootApplication
public class App {

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

}

5、创建业务层

/**
 * UsersService 接口实现类 *
 *
 */
@Service
public class UsersServiceImpl implements UsersService {
	@Autowired
	private UsersRepository usersRepository;

	@Override
	public List<Users> findUserAll() {
		return this.usersRepository.findAll();
	}

	@Override	
	//@Cacheable:对当前查询的对象做缓存处理
	@Cacheable(value = "users")
	public Users findUserById(Integer id) {
		return this.usersRepository.findOne(id);
	}

	@Override
	public Page<Users> findUserByPage(Pageable pageable) {
		return this.usersRepository.findAll(pageable);
	}

	@Override
	public void saveUsers(Users users) {
		this.usersRepository.save(users);
	}
}

6 修改实体类 Users

@Entity
@Table(name = "t_users")
public class Users implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private Integer id;
	@Column(name = "name")
	private String name;
	@Column(name = "age")
	private Integer age;
	@Column(name = "address")
	private String address;

	public Integer getId() {
		return id;
	}

	public void setId(Integer 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;
	}

	@Override
	public String toString() {
		return "Users [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
	}
}

7 测试

/**
 * UsersService 测试 *
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class UsersServiceTest {
	@Autowiredprivate
	UsersService usersService;

	@Test
	public void testFindUserById() { 
		// 第一次查询
		System.out.println(this.usersService.findUserById(1));
		//第二次查询
		System.out.println(this.usersService.findUserById(1));
	}
}

结果就是应该执行两次sql的查询语句,但是第二查询并没有执行,原因是因为从缓存里面取出类第一次查询的结果。

二、 @Cacheable 与@CacheEvict

1 @Cacheable

@Cacheable 作用:把方法的返回值添加到 Ehcache 中做缓存
Value 属性:指定一个 Ehcache 配置文件中的缓存策略,如果么有给定 value,name 	则 表示使用默认的缓存策略。

Key 属性:给存储的值起个名称。在查询时如果有名称相同的,那么则知己从缓存中将 	数据返回
1、业务层
    @Override
	@Cacheable(value = "users", key = "#pageable.pageSize")
	public Page<Users> findUserByPage(Pageable pageable) {
		return this.usersRepository.findAll(pageable);
	}
2、测试代码
    @Test
	public void testFindUserByPage() {
		Pageable pageable = new PageRequest(0, 2); // 第一次查询
		System.out.println(this.usersService.findUserByPage(pageable).getTotalElements());
		// 第二次查询
		System.out.println(this.usersService.findUserByPage(pageable).getTotalElements());
		// 第三次查询
		pageable = new PageRequest(1, 2);
		System.out.println(this.usersService.findUserByPage(pageable).getTotalElements());
	}

这里结果就是第一次查询,第二次没有sql语句查询,直接从缓存里面取,第三次执行类sql查询。

2 @CacheEvict

@CacheEvict 作用:清除缓存

@CacheEvict(value="users",allEntries=true)
public void saveUsers(Users users) {
	this.usersRepository.save(users); 
}

使用场景,比喻说,我们第一次查询数据库前两条数据添加类缓存,在我们将数据添加到数据库后,数据库对应前两条数据和缓存里面到数据就不一样类,这时我们要清除缓存,查询时重新添加缓存。

三、 Spring Boot 整合 Spring Data Redis

1、Linux安装 Redis

可以下载一个虚拟机进行测试
安装步骤省略,可以在网上找教程,写几个命令,面试用

1、安装 gcc

Yum install gcc-c++

2、解压 redis 压缩包

tar -zxvf redis-3.0.0.tar.gz

3、进入解压后的目录进行编译

cd redis-3.0.0
make

4、将 Redis 安装到指定目录

make PREFIX=/usr/local/redis install

5、启动 Redis

./redis-server

2、Spring Boot 整合 Spring Data Redis

Spring Data Redis 是属于 Spring Data 下的一个模块。作用就是简化对于 redis 的操做

1、修改 pom 文件添加 Spring Data Redis 的坐标
<!-- Spring Data Redis 的启动器 --> 
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> 
</dependency>
<!-- Test 的启动器 --> 
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> 
</dependency>
2、编写 Spring Data Redis 的配置类
/**
 * 完成对 Redis 的整合的一些配置 *
 */
@Configuration
public class RedisConfig {
	/**
	 * 1.创建 JedisPoolConfig 对象。在该对象中完成一些链接池配置 *
	 */
	@Bean
	public JedisPoolConfig jedisPoolConfig() {
		JedisPoolConfig config = new JedisPoolConfig();
		// 最大空闲数
		config.setMaxIdle(10);
		// 最小空闲数
		config.setMinIdle(5);
		// 最大链接数
		config.setMaxTotal(20);
		return config;
	}

	/**
	 * 2.创建 JedisConnectionFactory:配置 redis 链接信息
	 */
	@Bean
	public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config) {
		JedisConnectionFactory factory = new JedisConnectionFactory();
		// 关联链接池的配置对象
		factory.setPoolConfig(config);
		// 配置链接 Redis 的信息
		// 主机地址
		factory.setHostName("192.168.0.106"); 
		// 端口
		factory.setPort(6379);
		return factory;
	}

	/**
	* 3.创建 RedisTemplate:用于执行 Redis 操作的方法
	*/
	@Bean
	public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory factory) {
		RedisTemplate<String, Object> template = new RedisTemplate<>(); // 关联
		template.setConnectionFactory(factory);
		// 为 key 设置序列化器
		template.setKeySerializer(new StringRedisSerializer()); 
		// 为 value 设置序列化器
		template.setValueSerializer(new StringRedisSerializer());
		return template;
	}

}
3、编写测试代码,测试整合环境
/**
 * Spring Data Redis 测试 *
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = App.class)
public class RedisTest {
	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	/**
	 * 添加一个字符串
	 */
	@Test
	public void testSet() {
		this.redisTemplate.opsForValue().set("key", "北京尚学堂");
	}

	/**
	 * 获取一个字符串
	 */
	@Test
	public void testGet() {
		String value = (String) this.redisTemplate.opsForValue().get("key");
		System.out.println(value);
	}
}

3、提取 redis 的配置信息

1、在 src/main/resource/ 目录下新建一个配置文件:
application.properties
spring.redis.pool.max-idle=10
spring.redis.pool.min-idle=5
spring.redis.pool.max-total=20

spring.redis.hostName=192.168.0.106
spring.redis.port=6379
2、修改配置类
/**
 * 完成对 Redis 的整合的一些配置 *
 */
@Configuration
public class RedisConfig {
	/**
	 * 1.创建 JedisPoolConfig 对象。在该对象中完成一些链接池配置 *
	 */
	@Bean
	@ConfigurationProperties(prefix = "spring.redis.pool")
	public JedisPoolConfig jedisPoolConfig() {
		JedisPoolConfig config = new JedisPoolConfig();
		// 最大空闲数
		// config.setMaxIdle(10);
		// 最小空闲数
		// config.setMinIdle(5);
		// 最大链接数
		// config.setMaxTotal(20);
		System.out.println("默认值:" + config.getMaxIdle());
		System.out.println("默认值:" + config.getMinIdle());
		System.out.println("默认值:" + config.getMaxTotal());
		return config;
	}

	/**
	 * 2.创建 JedisConnectionFactory:配置 redis 链接信息
	 */
	@Bean
	@ConfigurationProperties(prefix = "spring.redis")
	public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig config) {
		System.out.println("配置完毕:" + config.getMaxIdle());
		System.out.println("配置完毕:" + config.getMinIdle());
		System.out.println("配置完毕:" + config.getMaxTotal());
		JedisConnectionFactory factory = new JedisConnectionFactory();
		// 关联链接池的配置对象
		factory.setPoolConfig(config);
		// 配置链接 Redis 的信息
		// 主机地址
		//factory.setHostName("192.168.0.106");
		// 端口
		//factory.setPort(6379);
		return factory;
	}

	/**
	 * 3.创建 RedisTemplate:用于执行 Redis 操作的方法
	 */
	@Bean
	public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory factory) {
		RedisTemplate<String, Object> template = new RedisTemplate<>(); // 关联
		template.setConnectionFactory(factory);
		// 为 key 设置序列化器
		template.setKeySerializer(new StringRedisSerializer());
		// 为 value 设置序列化器
		template.setValueSerializer(new StringRedisSerializer());
		return template;
	}

}

4 Spring Data Redis 操作实体对象

public class Users implements Serializable {
	private Integer id;
	private String name;
	private Integer age;
	public Integer getId() {
		return id;
	}
	public void setId(Integer 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;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Users [id=" + id + ", name=" + name + ", age=" + age +"]";
	}
}

实现序列化接口Serializable

测试

@Test
	public void testSetUesrs() {
		Users users = new Users();
		users.setAge(20);
		users.setName("json");
		users.setId(1); // 重新设置序列化器
		this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
		this.redisTemplate.opsForValue().set("users", users);
	}

	/**
	 * 取 Users 对象
	 */
	@Test
	public void testGetUsers() { // 重新设置序列化器
		this.redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
		Users users = (Users) this.redisTemplate.opsForValue().get("users");
		System.out.println(users);
	}

Spring Data Redis 以 JSON 格式存储实体对象

/**
	 * 基于 JSON 格式存 Users 对象
	 */
	@Test
	public void testSetUsersUseJSON() {
		Users users = new Users();
		users.setAge(20);
		users.setName("json");
		users.setId(1);
		this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
		this.redisTemplate.opsForValue().set("users_json", users);
	}

	/**
	 * 基于 JSON 格式取 Users 对象
	 */
	@Test
	public void testGetUseJSON() {
		this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Users.class));
		Users users = (Users) this.redisTemplate.opsForValue().get("users_json");
		System.out.println(users);
	}

上一篇:Spring Boot 异常处理与单元测试(五)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老徐··

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值