SpringBoot使用Redis和MyBatis完成緩存數據的增刪改查

1.在Spring Boot中集成Redis

1)添加依賴
pom.xml
添加的依賴包含Redis,Mysql,MyBatis,fastjson,junit

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

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.0.0</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

2)配置application.properties

application.properties
配置mysql,redis服務器



spring.datasource.url=jdbc:mysql://127.0.0.1/book?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql= true

spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:db/schema.sql


# Redis數據庫索引(默認爲0)
spring.redis.database=1
# Redis服務器地址
spring.redis.host=127.0.0.1
# Redis服務器連接端口
spring.redis.port=6379
# Redis服務器連接密碼(默認爲空)
spring.redis.password=

# 連接池最大連接數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=8


# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=-1


# 連接池中的最大空閒連接
spring.redis.jedis.pool.max-idle=8


# 連接池中的最小空閒連接
spring.redis.jedis.pool.min-idle=0

# 連接超時時間(毫秒)
spring.redis.timeout=5000

3)在入口類加上@EnableCaching註解,開啓緩存支持

RedisDemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class RedisDemoApplication {

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

}

4)建立下面的項目結構
在這裏插入圖片描述

2.配置Redis類

要想啓動Spring緩存支持,需要創建一個CacheManager的Bean。

RedisConfig.java

package com.example.demo.config;

import  com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import  org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;

@Configuration

public class RedisConfig extends  CachingConfigurerSupport{
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    @SuppressWarnings("rawtypes")
    @Bean
    //緩存管理器

    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheManager cacheManager = RedisCacheManager.create(connectionFactory);
        //設置緩存過期時間

        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        //配置連接工廠
        StringRedisTemplate template = new StringRedisTemplate(factory);

        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis 的value值
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();

        //指定要序列化的域,field,get和set,以及修飾符範圍
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        //指定序列化輸入的類型,類必須是非final類
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //序列化配置爲String格式
        template.setValueSerializer(new StringRedisSerializer());

        //
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

}


關於Redis Template中序列化和反序列化配置的解釋

關於數據的“序列化/反序列化”,提供了多種可選擇策略(RedisSerializer)

序列化/發序列化 解釋
JdkSerializationRedisSerializer POJO對象的存取場景,使用JDK本身序列化機制,將pojo類通過ObjectInputStream/ObjectOutputStream進行序列化操作,最終redis-server中將存儲字節序列。
StringRedisSerializer 適用於Key或者value爲字符串的場景,根據指定的charset對數據的字節序列編碼成string
JacksonJsonRedisSerializer 提供了javabean與json之間的轉換能力,可以將pojo實例序列化成json格式存儲在redis中,也可以將json格式的數據轉換成pojo實例。
OxmSerializer 提供了將javabean與xml之間的轉換能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存儲的數據將是xml工具。

上面4種策略中:

JdkSerializationRedisSerializerStringRedisSerializer是最基礎的策略,在設計時仍然不推薦直接使用後面兩種,即JacksonJsonRedisSerializerOxmSerializer,因爲無論是json還是xml,他們本身仍然是String。

如果數據需要被第三方工具解析,那麼數據應該使用StringRedisSerializer而不是JdkSerializationRedisSerializer

如果數據格式必須爲json或者xml,那麼在編程級別,在redisTemplate配置中仍然使用StringRedisSerializer,在存儲之前或者讀取之後,使用“SerializationUtils”工具轉換轉換成json或者xml

3.創建測試實體類

User.java

package com.example.demo.model;

import lombok.Data;

import java.io.Serializable;

@Data
public class User implements Serializable {
    private  String id;
    private  String name;
    private int age;
}

這裏需要注意的是spring boot在啓動時會自動創建user表
在項目的resources目錄下新建db目錄,並添加schema.sql文件,寫入創建user表的sql語句
當然還需要配置數據庫連接,並加上數據表初始化的配置(配置工作前面的文件中已經包含)
這裏是schema.sql

DROP TABLE IF EXISTS user;
--IF object_id('user','U') is not NULL drop table 'user';
CREATE TABLE user(
    id int(11) NOT NULL AUTO_INCREMENT,
    name varchar(255) DEFAULT NULL,
    age int(11) DEFAULT NULL,
    PRIMARY KEY (id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.實現實體和數據表的映射關係

UserMapper.java

package com.example.demo.mapper;

import com.example.demo.model.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import  org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import  org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;

@Repository
@Mapper
public interface UserMapper {
    @Insert("insert into user(name,age) values(#{name},#{age})")
    int addUser(@Param("name")String name,@Param("age")String age);

    @Select("select * from user where id=#{id}")
    User findById(@Param("id")String id);
    @Update("update user set name=#{name},age=#{age} where id=#{id}")
    int updateById(User user);

    @Delete("delete from user where id=#{id}")
    void deleteById(@Param("id")String id);
}


5.創建Redis緩存服務器

創建Redis緩存服務器,即緩存在服務器層面
UserService.java

代碼解釋
@Cacheable:將查詢結果緩存到Redis中
key="#p0":指定傳入的第一個參數作爲Redis的key
@CachePut:指定key,將更新的結果同步到Redis中
@CacheEvict:指定key,刪除緩存數據
allEntries:方法調用後將立即清除緩存

package com.example.demo.service;

import com.example.demo.model.User;
import com.example.demo.mapper.UserMapper;
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;

//Redis緩存服務層
@Service
@CacheConfig(cacheNames = "users")
public class UserService {
    @Autowired
    UserMapper userMapper;
    @Cacheable(key="#p0")
    public User selectUser(String id){
        System.out.println("select");
        return userMapper.findById(id);
    }

    @CachePut(key="#p0")
    public  void updateById(User user){
        System.out.println("uddate");
        userMapper.updateById(user);
    }
    //如果allEntries指定爲true,則調用CacheEvict方法後將立即清空所有緩存

    @CacheEvict(key="#p0",allEntries = true)
    public void deleteById(String id){
        System.out.println("delete");
        userMapper.deleteById(id);
    }
}

6.完成增刪改查測試API

RedisController.java

package com.example.demo.controller;
import com.example.demo.service.UserService;
import com.example.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/user")
public class RedisController {
    @Autowired
    UserService userService;

    @RequestMapping("/{id}")
    public User ForTest(@PathVariable String id){
        return userService.selectUser(id);
    }

    @RequestMapping( "/update/")
    public String update(User user){

        userService.updateById(user);
        return "success";
    }


    @RequestMapping( "/delete/{id}")
    public String delete (@PathVariable String id){
        userService.deleteById(id);
        return "delete success";
    }

}

7.啓動測試

1)啓動Redis服務
由於沒有設置環境變量,需要手動進入到Redis安裝目錄cd /d D:\Redis-x64-3.2.100,然後啓動服務

redis-server.exe redis.windows.conf

在cmd窗口打開的情況下,運行項目
在這裏插入圖片描述
2)多次訪問

http://localhost:8080/user/2

第一次時控制檯會出現select信息,代表對數據庫進行了查詢操作。後面再訪問則不會出現提示,表示沒有對數據庫執行操作,而是使用Redis中的緩存數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章