SpringBoot 整合Redis缓存,使用Docker做Redis容器

如果我的博客能够帮到大家能够点个赞,关注一下,以后还会更新更过JavaWeb的高级技术,大家的支持就是我继续更新的动力。谢谢咯。

        在日常得开发中,JavaWeb项目中经常需要使用缓存,加快系统得访问速度。有利于用户更好的用户体验。以下是SpringBoot整合Redis的案例,仅供参考。

一、环境搭建

  •  导入依赖
<!--引入缓存组件-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
  • 编写实体类 DepartMent.java 和 Employee.java
package com.nyist.cache.model;

import java.io.Serializable;

public class Department implements Serializable {
	
	private Integer id;
	private String departmentName;
	
	
	public Department() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Department(Integer id, String departmentName) {
		super();
		this.id = id;
		this.departmentName = departmentName;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", departmentName=" + departmentName + "]";
	}
}



package com.nyist.cache.model;

import java.io.Serializable;

public class Employee implements Serializable {
	
	private Integer id;
	private String lastName;
	private String email;
	private Integer gender; //性别 1男  0女
	private Integer dId;
	
	
	public Employee() {
		super();
	}

	
	public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
		this.dId = dId;
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Integer getGender() {
		return gender;
	}
	public void setGender(Integer gender) {
		this.gender = gender;
	}
	public Integer getdId() {
		return dId;
	}
	public void setdId(Integer dId) {
		this.dId = dId;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
				+ dId + "]";
	}
}
  • 配置数据源
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/spring_cache?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    type: com.alibaba.druid.pool.DruidDataSource

    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,logback
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
  #指定链接的Redis
  redis:
    host: 192.168.1.110


#mybatis 开启驼峰命名法
mybatis:
  configuration:
    map-underscore-to-camel-case: true

#设置日志等级
logging:
  level:
    com.nyist.cache.mapper: debug
#打开控制报告
#debug: true

  • 配置Mapper DepartmentMapper.java 和 EmployeeMapper.java
package com.nyist.cache.mapper;

import com.nyist.cache.model.Department;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface DepartmentMapper {

    @Select("select * from department where id=#{id}")
    Department getDeptById(Integer id);
}




package com.nyist.cache.mapper;

import com.nyist.cache.model.Employee;
import org.apache.ibatis.annotations.*;

@Mapper
public interface EmployeeMapper {

    @Select("select * from employee where  id = #{id}")
    public Employee getEmpById(Integer id);

    @Update("update employee set lastName = #{lastName},email=#{email},gender=#{gender} where id=#{id}")
    public void updateEmp(Employee employee);


    @Delete("delete from employee where id = #{id}")
    public void deleteEmp(Integer id);


    @Insert("insert into employee(lastName,email,gender,d_id) values(#{lastName},#{email},#{gender},#{d_id})")
    public void insertEmp(Employee employee);


    @Select("select * from employee where lastName = #{lastName}")
    Employee getEmpByLastName(String lastName);
}
  • config配置 MyRedisConfiguration.java
package com.nyist.cache.comfig;

import com.nyist.cache.model.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

//开启自定义序列化
@Configuration
public class MyRedisConfiguration {

    @Bean   //加入到容器中去
    public RedisTemplate<Object, Employee> empredisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Employee> redisTemplate = new RedisTemplate<Object, Employee>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //转换为json 保存到redis数据库中
        Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer<Employee>(Employee.class);
        redisTemplate.setDefaultSerializer(serializer);
        return redisTemplate;
    }

}
  • servic层 DeptService.java 和 EmployeeService.java
package com.nyist.cache.service;

import com.nyist.cache.mapper.EmployeeMapper;
import com.nyist.cache.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;

//用于抽取公共配置
@CacheConfig(cacheNames = "emp")
@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 将方法的运行结果进行缓存,以后再要使用相同的数据,直接从缓存中拿,不调用方法。
     * CacheManager 管理多个缓存Cache组件,对缓存的真正CRUD操作在Cache 组件中,每一个缓存组件有一个唯一一个名字
     * 几个属性:
     *      cacheNames/valye:指定缓存组件的名字
     *      key:缓存数据时的key,可以用它来指定。  默认使用方法参数的值 1-方法的返回值
     *          可以编写SPEL 表达式 #id;参数id的值, #a0 #p0 #root.args[0]
     *
     *      keyGenerator:key 得生成器,可以自己指定key的生成器的组件ID
     *          key/keyGenerator:二选一
     *      cacheManager:指定缓存管理器,或者cacheResolver指定获取缓存解析器。
     *      condition:符合条件的情况下才缓存。
     *      unless:是否缓存,当unless指定的条件为true,方法的返回值不会被缓存,可以根据结果进行判断
     *      sync:是否使用异步模式
     * @param id
     * @return
     */
    /***
     * @Cacheable(condition="#id>0",cacheNames={"emp"})
     * //指定key getEmp(2)
     * @Cacheable(cacheNames = {"emp"},key="#root.methodName+'['+#id+']'")
     * @Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator",condition = "#a0>1 and #root.methodName eq 'aaa'")
     *
     * @param id
     * @return
     */
    @Cacheable(cacheNames = {"emp"},key = "#id")/*,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#p0==2")*/
    public Employee getEmp(Integer id){
        System.out.println("查询:"+id);
        Employee empById = employeeMapper.getEmpById(id);
        return empById;
    }


    //更新的调用
    @CachePut(key = "#employee.id",value = "emp")
    public Employee updateEmp(Employee employee){
        employeeMapper.updateEmp(employee);
        return  employee;
    }

    //allEntries默认为fale 若改为true 则删除缓存的时候 会全部和删除
    //beforeInvocation 是否在方法之前调用,默认为false,当等于true的时候 即为在方法之前调用
    //删除  清空缓存
    @CacheEvict(cacheNames = "emp",key = "#id")
    public void deleteEmp(Integer id){
        System.out.println("DeleteId:"+id);
        employeeMapper.deleteEmp(id);
    }

    //定义复杂缓存规则
    /***
     * 1.使用 lastName查询数据库将查询的结果放入缓存中
     * 2.在使用 id 和 email 查询 同样可以查询到 不需要发送SQL查询数据库,只查询缓存就可以查询到数据
     * 3.所以配置的Caching 正确
     * @param lastName
     * @return
     */
    @Caching(
            cacheable = {
                //根据 lastName查询缓存 如果缓存中没有这条数据记录,将其放入缓存中
                @Cacheable(cacheNames="emp",key = "#lastName")
            },
            put = {
                //可以根据id 和 邮箱更新缓存
                @CachePut(cacheNames = "emp",key = "#result.id"),
                @CachePut(cacheNames="emp",key = "#result.email")
            }
    )
    public Employee getEmoByLastName(String lastName){
        Employee employee = employeeMapper.getEmpByLastName(lastName);
        return employee;
    }
}







package com.nyist.cache.service;

import com.nyist.cache.mapper.DepartmentMapper;
import com.nyist.cache.model.Department;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.stereotype.Service;

//使用缓存管理器
@CacheConfig(cacheManager = "redisCacheManager")
@Service
public class DeptService {
    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    RedisCacheManager redisCacheManager;

    //默认key 为Id
    @Cacheable(cacheNames = "dept")
    public Department getDept(Integer id){
        System.out.println("查询部门:"+id);
        Department department = departmentMapper.getDeptById(id);

        return department;
    }

    //编码方式  用来缓存数据
    public Department getDeptById(Integer id){
        //使用编码的方式 来缓存数据
        Department department = null;
        Cache dept = redisCacheManager.getCache("dept");
        department = departmentMapper.getDeptById(id);
        //获取某个缓存
        dept.put("dept:1",department);
        return department;
    }
}
  • controller DeptController 和 EmployeeController
package com.nyist.cache.controller;

import com.nyist.cache.model.Department;
import com.nyist.cache.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DeptController {

    @Autowired
    DeptService deptService;

    //缓存的数据能够保存到Redis
    //第二次从缓存中查询不能够被反序列化
    @GetMapping("/dept/{id}")
    public Department getDeptById(@PathVariable("id") Integer id){
        Department dept = deptService.getDept(id);
        return dept;
    }

    @GetMapping("/getDeptById/{id}")
    public Department getDept(@PathVariable("id") Integer id){
        Department department = deptService.getDeptById(id);
        return department;
    }
}








package com.nyist.cache.controller;

import com.nyist.cache.model.Employee;
import com.nyist.cache.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class EmployeeController {

    @Autowired
    EmployeeService employeeService;

    @GetMapping("/emp/{id}")
    public Employee getEmp(@PathVariable("id") Integer id){
        Employee emp = employeeService.getEmp(id);
        return emp;
    }


    @GetMapping("/emp")
    public Employee update(Employee employee){
        System.out.println("employee:"+employee);
        Employee employee1 = employeeService.updateEmp(employee);
        return employee1;
    }

    @GetMapping("/demp/{id}")
    public void deleteEmp(@PathVariable("id") Integer id){
        System.out.println("deleteEmp:"+id);
        employeeService.deleteEmp(id);
        System.out.println("删除成功!!!");
    }

    @GetMapping("/getEmpByLastName/{lastName}")
    public Employee getEmpByLastName(@PathVariable("lastName") String lastName){
        Employee emoByLastName = employeeService.getEmoByLastName(lastName);
        return emoByLastName;
    }
}
  • 测试类
package com.nyist.cache;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.nyist.cache.mapper.EmployeeMapper;
import com.nyist.cache.model.Employee;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jackson.JsonObjectDeserializer;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot01CacheApplicationTests {

    @Autowired
    EmployeeMapper employeeMapper;

    //操作k-v都是字符串
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    //操作k-v都是对象
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisTemplate<Object,Employee> empredisTemplate;
    /***
     * String(字符串)、List(列表)、Set(集合)、Hash(散列)、ZSet(有序集合)
     stringRedisTemplate.opsForValue(); 操作字符串
     stringRedisTemplate.opsForList();  操作列表的
     stringRedisTemplate.opsForSet();   操作集合的
     stringRedisTemplate.opsForHash();  操作散列的
     stringRedisTemplate.opsForZSet();  操作有序集合的
     *
     */
    @Test
    public void testRedis(){
        //给redis中保存了一个数据
       // stringRedisTemplate.opsForValue().append("msg","hello");
        String msg = stringRedisTemplate.opsForValue().get("msg");
        System.out.println(msg);
        System.out.println("\n*****************操列表*******************\n");
        stringRedisTemplate.opsForList().leftPush("myList","1");
        stringRedisTemplate.opsForList().leftPush("myList","2");
    }

    //测试保存对象
    @Test
    public void save(){
        //默认如果保存对象,使用jdk序列化机制,序列化后的数据保存在redis中。
        //redisTemplate.opsForValue().set("emp01",empById);
        //1.将数据库以json的格式保存
            //(1)将自己的对象转换为json
            //(2)redisTemplats默认的序列化规则;改变默认的序列化规则
        Employee empById = employeeMapper.getEmpById(3);
//        redisTemplate.opsForValue().set("emp01",empById);
//        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(empById));
//        redisTemplate.opsForValue().set("emp02",jsonObject.toJSONString());
        empredisTemplate.opsForValue().set("emp04",empById);
    }

    @Test
    public void contextLoads() {
        Employee empById = employeeMapper.getEmpById(1);
        System.out.println(empById);
    }

}

  • 使用Docker做Redis容器
  1. 在中央仓库查找redis  docker search redis
  2. 从中央仓库下载到本地   docker pull redis
  3. 下载好本地镜像 开始制作容器   docker run -d -p 6379:6379 --name myRedis [tag名称]
  4. 查看启动的Redis     docker ps 
  • 使用Redis Desktop Manager 连接虚拟机中的Docker容器中启动的Redis容器

 

项目结构图:

 

源码下载:下载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值