Redis之数据缓存

1.缓存架构简介

每次请求获取数据的时候,都需要查询数据库,这种时候,高并发、大数据环境中就会造成系统瓶颈,数据库不稳定甚至宕机。通过给系统中加入缓存功能,就可以提高数据的查询速度,降低数据服务器的io负载压力,当对mysql数据库进行dml操作时(CRUD),需要对缓存中的数据进行更新,实现缓存同步,否则会出现数据脏读(读取未提交数据)。
在这里插入图片描述

2.搭建项目

在这里插入图片描述

3.配置application.yml

#配置mysql数据库连接
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis
    username: root
    password: root
  #配置redis数据库连接
  redis:
    host: 192.168.126.10
    port: 6379
mybatis:
  type-aliases-package: com.yd.app.pojo
  mapper-locations: classpath:/mapper/*.xml

2.创建实体类

	private Integer uid;
    private String uname;
    private String password;
    private String address;

3.创建UserMapper接口

@Mapper
public interface UsersMapper {
    /***
     *根据用户id查询用户信息
     */
    public Users loadUsersByIdMapper(Integer id);
    /***
     * 实现用户信息更新
     */
    public void updateUsersMapper(Users users);
    /***
     * 实现用户信息删除
     */
    public void deleteUsersMapper(Integer id);
}

4.UserMapper.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.xhx.app.mapper.UsersMapper">
    <!--实现用户信息分页查询-->
    <select id="loadUsersByIdMapper" resultType="Users" parameterType="java.lang.Integer">
        select * from users where uid=#{uid}
    </select>
    <!--实现用户信息更新-->
    <update id="updateUsersMapper" parameterType="Users">
        update users set uname=#{uname},password=#{password},address=#{address} where uid=#{uid}
    </update>
    <!--实现用户信息删除-->
    <delete id="deleteUsersMapper" parameterType="java.lang.Integer">
        delete from users where uid=#{uid}
    </delete>
</mapper>


5.UserService接口

public interface UsersService {
    /***
     * 查询某个用户信息
     */
    public Users loadUsersService(Integer id);
    /***
     * 更新某个用户信息
     */
    public Users updateUsersService(Users users);
    /***
     * 删除用户信息
     */
    public void deleteUsersService(Integer id);

}

6.service的实现类

    @Autowired  //注入Mapper对象
    private UsersMapper usersMapper;
    /***
     * @Cacheable 作用将方法的返回值进行缓存,保存redis数据库,属于aop编程的前置增强
     *            在进入方法之前先查询redis数据 如果能查询到,直接返回查询结果。如果查询不到,进入方法查询数据库。
     * cacheNames : 自己给缓存起的名字
     * key: 指定redis数据库的key,可以通过springEL表达式指定
     *      #id : 获得方法的实参作为redis的键
     *      #p0 :获得方法的第一个实参作为redis的键
     *      #users.id
     *      #p0.id
     */
    @Cacheable(cacheNames = {"user_cahe"},key = "#id")
    @Override
    public Users loadUsersService(Integer id) {
        System.out.println(id+"------------查询数据库获得用户信息");
        return usersMapper.loadUsersByIdMapper(id);
    }

    /***
     * 将缓存中的数据进行同步,通过指定key缓存方法的返回值
     * 而方法的参数就是更的最新数据,覆盖原来的数据
     * 每更新一次都会进入业务方法,完成数据库更新
     * @param users
     */
    @CachePut(cacheNames = "user_cahe",key ="#users.uid")
    @Override
    public Users updateUsersService(Users users) {
        System.out.println("--------------更新用户信息");
        usersMapper.updateUsersMapper(users);

        return users;
    }

    /****
     * 进行缓存同步,删除redis数据库数据
     * @param id
     */
    @CacheEvict(cacheNames = {"user_cahe"},key = "#id")
    @Override
    public void deleteUsersService(Integer id) {
        System.out.println("--------------删除用户信息");
        usersMapper.deleteUsersMapper(id);
    }
}

7.启动类添加注解

@SpringBootApplication
@EnableCaching  //开启缓存功能
public class Application {
   public static void main(String[] args) {
      SpringApplication.run(Application.class, args);
   }

}

8.测试类(使用注解实现缓存)

@SpringBootTest
class ApplicationTests {

   @Test
   void contextLoads() {
   }

   //注入UsersService对象
   @Autowired
   private UsersService usersService;

   /***
    * 查询某个用户信息
    */
   @Test
   public void loadUesrsServiceTest(){
      Users users = usersService.loadUsersService(2);
      System.out.println(users.getUid()+"\t"+users.getUname()+"\t"+users.getAddress());
   }


    /****
     *测试用户信息更新
     */
    @Test
    public void updateUsersServiceTest(){
        Users users=new Users();
        users.setUid(2);
        users.setUname("小小");
        users.setAddress("北京");
        users.setPassword("888888");
        usersService.updateUsersService(users);
    }

    /****
     * 测试用户信息删除
     */
    @Test
    public void deleteUsersServiceTest(){
        usersService.deleteUsersService(1);
    }

}

9.覆盖注解缓存的序列化方式

@Configuration
public class RedisConfig {
    /***
     * 自己实例化RedisTemplate对象
     * <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"></bean>
     */
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    @Bean
    public CacheManager cacheManager(){
        //创建StringRedisSerializer对象
        StringRedisSerializer key=new StringRedisSerializer();
        //创建GenericJackson2JsonRedisSerializer对
        GenericJackson2JsonRedisSerializer value=new GenericJackson2JsonRedisSerializer();
        //进行注解缓存的配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(key))   .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(value));

        //创建RedisCacheManager对象
        RedisCacheManager cacheManager= RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}


版权声明:本文为qsqxhx原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。