配置数据库文件
application.properties
# ============数据库============
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=abcde
# ============mybatis============
mybatis.mapper-locations=classpath:/mapper/*.xml
mybatis.type-aliases-package=com.codel.cacheredis.pojo
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# ============redis============
#reids相关配置
#redis服务器地址
spring.redis.host=localhost
#雷迪森服务器端口
spring.redis.port=6379
#redis密码,默认为空
spring.redis.password=
#redis数据库索引(默认为0)
spring.redis.database=0
#连接池对打阻塞等待时间(负表示没有限制)
spring.redis.jedis.pool.max-wait=10000
#连接池最大连接数(负表示没有限制)
spring.redis.jedis.pool.max-active=100
#连接池中的最大空闲链接
spring.redis.jedis.pool.max-idle=20
#连接池中的最小空闲链接
spring.redis.jedis.pool.min-idle=0
#链接超时时间
spring.redis.timeout=3000
#redis缓存时间为1分钟
spring.cache.redis.time-to-live=30000
配置架包:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- mybatis 持久层-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
配置实体类和dao层mapper接口:
user实体类:要序列化
UserMapper :
package com.codel.cacheredis.dao;
import com.codel.cacheredis.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
@Mapper
public interface UserMapper {
/**
* 增加
*
* @param user
* @return
*/
public int addUser(User user);
/**
* 删除
*
* @param id
* @return
*/
public int deleteUser(@Param("id") int id);
/**
* 修改
*
* @param user
* @return
*/
public int updateUser(User user);
/**
* 查询获取所有User对象
*
* @return
*/
public List<User> selectUser();
/**
* 根据id查询获取某个User对象
*
* @param id
* @return
*/
public User selectUserById(@Param("id") int id);
/**
* 查询一共有几条数据
*
* @return
*/
public int countUser();
}
mapper对应的mapper.xml配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.codel.cacheredis.dao.UserMapper">
<insert id="addUser" parameterType="user">
insert into user (name, password)
values (#{name}, #{password})
</insert>
<delete id="deleteUser" parameterType="int">
delete
from user
where id = #{id}
</delete>
<update id="updateUser" parameterType="user">
update user
set name=#{name},
password=#{password}
where id = #{id}
</update>
<select id="selectUser" resultType="com.codel.cacheredis.pojo.User">
select *
from user
</select>
<select id="selectUserById" parameterType="int" resultType="com.codel.cacheredis.pojo.User">
select *
from user
where id = #{id}
</select>
<select id="countUser" resultType="java.lang.Integer">
select count(*)
from user
</select>
</mapper>
UserService和UserServiceImpl
UserService接口同UserMapper的内容一样,略。
这是使用注解的方式进行配置redis缓存:
UserServiceImpl:
package com.codel.cacheredis.service.impl;
import com.codel.cacheredis.dao.UserMapper;
import com.codel.cacheredis.pojo.User;
import com.codel.cacheredis.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.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Override
@CachePut(key = "'user-id-'+ #user.id")
public int addUser(User user) {
System.out.println("写入缓存");
return userMapper.addUser(user);
}
@Override
@CacheEvict(key = "'user-id-'+#p0")//根据key清除缓存,一般该注解标注在修改和删除方法上
public int deleteUser(int id) {
return userMapper.deleteUser(id);
}
@Override
@CacheEvict(key = "'user-id-'+#user.id")//根据key清除缓存,一般该注解标注在修改和删除方法上
public int updateUser(User user) {
System.out.println("更新数据并清除之前的缓存");
return userMapper.updateUser(user);
}
@Override
@Cacheable(cacheNames = "userList") // 标志读取缓存操作,如果缓存不存在,则调用目标方法,并将结果放入缓存
public List<User> selectUser() {
System.out.println("缓存不存在,执行方法");
return userMapper.selectUser();
}
@Override
@Cacheable(key = "'user-id-'+#p0")
public User selectUserById(int id) {
System.out.println("缓存不存在,执行方法");
return userMapper.selectUserById(id);
}
@Override
public int countUser() {
return userMapper.countUser();
}
}
这是利用了API进行配置的redis缓存:
package com.codel.cacheredis.service.impl;
import com.codel.cacheredis.dao.UserMapper;
import com.codel.cacheredis.pojo.User;
import com.codel.cacheredis.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class APIUserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public int addUser(User user) {
return 0;
}
@Override
public int deleteUser(int id) {
return 0;
}
@Override
public int updateUser(User user) {
return 0;
}
@Override
public List<User> selectUser() {
Object list= redisTemplate.opsForValue().get("userList_id");
if (list != null) {
System.out.println(list);
return (List<User>) list;
} else {
// 没有就查询数据库的,然后将结果进行缓存
List<User> users = userMapper.selectUser();
redisTemplate.opsForValue().set("userList_id", users, 1, TimeUnit.DAYS);
// 后面的timeunit设置缓存时间的
return users;
}
}
//
@Override
public User selectUserById(int id) {
// 先查询redis缓存数据库里面的数据
Object object = redisTemplate.opsForValue().get("api_id" + id);
if (object != null) {
System.out.println(object);
return (User) object;
} else {
// 没有就查询数据库的,然后将结果进行缓存
User user = userMapper.selectUserById(id);
redisTemplate.opsForValue().set("api_id" + id, user, 1, TimeUnit.DAYS);
// 后面的timeunit设置缓存时间的
return user;
}
}
@Override
public int countUser() {
return 0;
}
}
两种方式都可以进行redis缓存,但是使用java自带的序列化机制导致数据不好看,所有会自定义redis序列化机制
package com.codel.cacheredis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
//这个配置类是连接redis的,是自定义的,用于定义数据的序列化格式
@Configuration
@SuppressWarnings("all")
//开启redis缓存
@EnableCaching
public class RedisConfig {
//构建RedisConfig配置类
// 这个是基于注解的方式进行扩展
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 使用json格式序列化对象,对缓存数据key和value进行转换
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题) 定制缓存数据序列化方式及时效
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofDays(1))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
// 配置一个基于api方式的配置bean ,对redis的key和value进行序列化的设置
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 使用json格式序列化对象,对缓存数据key和value进行转换
Jackson2JsonRedisSerializer jsonSerializer = new Jackson2JsonRedisSerializer(Object.class);
// 解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jsonSerializer.setObjectMapper(om);
// 设置redistemplaate模板api的序列化方式为json
template.setDefaultSerializer(jsonSerializer);
return template;
}
}