• 【redis-01】redis整合springboot实现简单的增删改查


    【redis-01】redis整合springboot实现简单的增删改查

    (1)基本的环境配置
    1-添加相关的依赖

    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <!-- web -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <!-- redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
            <!-- Jedis客户端依赖 -->
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>3.3.0</version>
            </dependency>
    
            <!-- redisson -->
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.6.5</version>
            </dependency>
    
            <!-- 通用池 -->
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
            </dependency>
    
            <!-- mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.21</version>
            </dependency>
    
            <!-- mybatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.2</version>
            </dependency>
    
            <!-- 不想写sql,通用mapper -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>2.1.5</version>
            </dependency>
    
            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <!-- test测试用例 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
    
        </dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    2-添加配置

    server.port=8080
    
    #mysql数据源
    spring.mvc.view.prefix=/WEB-INF/jsp/
    spring.mvc.view.suffix=.jsp
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/suanzhang?characterEncoding=UTF-8
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.jpa.properties.hibernate.hbm2ddl.auto=update
    
    ###########################redis#########################
    #Redis数据库索引(默认为0)
    spring.redis.database=0
    #Redis服务器地址
    spring.redis.host=127.0.0.1
    #Redis服务器连接端口
    spring.redis.port=6379
    #Redis服务器连接密码(默认为空)
    spring.redis.password=
    
    spring.jpa.show-sql=true
    
    #打印sql
    logging.level.com.allen.hello_redis.Mapper:debug
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    (2)基本的代码准备
    1-准备数据库和数据表
    2-创建实体类

    public class EmployeeTemp {
        private int id;
        private String name;
    
        //手动添加无参构造方法,否则会出现redis反序列化失败的情况
        public EmployeeTemp(){
    
        };
        public EmployeeTemp(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3-创建mapper层

    @Mapper
    public interface EmpMapper{
    
        @Select("select * from employee where id = #{id}")
        public Employee findEmpById(int id);
    
        @Delete("delete from employee where id=#{id}")
        public void deleteEmpById(int id);
    
        @Update("update employee set name=#{name} where id=#{id}")
        public void update(Employee employee);
    
        @Insert("insert into employee (name) values (#{name})")
        public int insert01(Employee employee);
    
        @Select("select * from employee")
        public List<Employee> findAll();
    
        @Select("delete from employee")
        public void deleteAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4-创建service层

    @Service
    @Slf4j
    public class EmployeeServiceImpl implements EmployeeService {
    
        @Autowired
        EmpMapper empMapper;
    
        @Autowired
        public RedisTemplate redisTemplate;
    
        /*第二部分:不使用注解实现操作redis和mysql数据*/
        @Override
        public void insert01(EmployeeTemp employeeTemp) {
            Object empObj = redisTemplate.opsForValue().get("emp:"+employeeTemp.getId());
            if(empObj==null){
                //要插入缓存
                System.out.println("——————》需要插入缓存");
                redisTemplate.opsForValue().set("emp:"+employeeTemp.getId(),employeeTemp);
            } else {
                //查询数据库
                System.out.println("——————》不需要插入缓存");
            }
            System.out.println("——————》需要插入数据库");
            empMapper.insert02(employeeTemp);
    
        }
    
        @Override
        public void update01(EmployeeTemp employeeTemp) {
            Object empObj = redisTemplate.opsForValue().get("emp:"+employeeTemp.getId());
            if(empObj==null){
                //要插入缓存
                System.out.println("——————》需要插入缓存");
                redisTemplate.opsForValue().set("emp:"+employeeTemp.getId(),employeeTemp);
            } else {
                //查询数据库
                System.out.println("——————》需要更新缓存");
                redisTemplate.opsForValue().set("emp:"+employeeTemp.getId(),employeeTemp);
            }
            System.out.println("——————》需要更新数据库");
            empMapper.update02(employeeTemp);
    
        }
    
        @Override
        public void delete01(int id) {
            Object empObj = redisTemplate.opsForValue().get("emp:"+id);
            if(empObj==null){
                System.out.println("——————》不用删除缓存");
            } else {
                System.out.println("——————》删除缓存");
                redisTemplate.delete("emp:"+id);
            }
            System.out.println("——————》删除数据库");
            empMapper.deleteEmpById(id);
        }
    
        @Override
        public Object findEmpById01(int id) {
            //先从缓存中获取数据,如果有就直接返回
            //如果缓存里没有数据,则查询mysql,并将数据设置到缓存中去
            Object empObj = redisTemplate.opsForValue().get("emp:"+id);
            if(empObj==null){
                //查询数据库
                System.out.println("——————》查询数据库");
                EmployeeTemp employee = empMapper.findEmpById02(id);
                System.out.println(employee);
                redisTemplate.opsForValue().set("emp:"+id,employee);
                return employee;
            } else {
                System.out.println("——————》查询缓存");
            }
            return empObj;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    5-创建控制层

    @RestController
    public class RedisController {
    
        //springboot会根据引入的依赖在ioc中自动的创建这些bean,所以可以直接引用
        @Autowired
        private RedisTemplate redisTemplate;
    
        @Autowired
        private EmployeeServiceImpl employeeService;
    
    
        /*第一部分:测试redisTemplate的方法,直接操作redis的数据*/
        // http://localhost:8080/redis/get/name
        @GetMapping("/redis/get/{key}")
        public Object get(@PathVariable("key") String key) {
            return redisTemplate.opsForValue().get(key);
        }
    
        // http://localhost:8080/redis/set/name/zhangsan
        @PostMapping("/redis/set/{key}/{value}")
        public Object set(
                @PathVariable("key") String key,
                @PathVariable("value") String value) {
            redisTemplate.opsForValue().set(key,value);
            return "set success";
        }
    
        /*第二部分:测试不用注解版本的redis加数据库的增删改查*/
        // http://localhost:8080/redis/insertEmp01/13/daqiao
        @PostMapping("/redis/insertEmp01/{id}/{name}")
        public Object insertEmp01(
                @PathVariable("id") int id,
                @PathVariable("name") String name) {
    
            employeeService.insert01(new EmployeeTemp(id,name));
            return "set success";
        }
    
        // http://localhost:8080/redis/deleteEmp01/14
        @PostMapping("/redis/deleteEmp01/{id}")
        public Object deleteEmp(@PathVariable("id") int id) {
            employeeService.delete01(id);
            return "delete success";
        }
    
        // http://localhost:8080/redis/findEmpById01/12
        @PostMapping("/redis/findEmpById01/{id}")
        public Object findEmpById01(@PathVariable("id") int id){
            Object employee = employeeService.findEmpById01(id);
            return employee;
        }
    
        //http://localhost:8080/redis/updateEmp01/2/1111
        @PostMapping("/redis/updateEmp01/{id}/{name}")
        public void updateEmp01(@PathVariable("id") int id,@PathVariable("name") String name) {
            EmployeeTemp employee = new EmployeeTemp(id,name);
            employeeService.update01(employee);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    根据链接分别测试增删改查的效果

    (3)分析序列化配置类
    在没有对序列化进行处理之前,存到redis里的信息都是乱码的,要想显示成可读的文字,需要进行序列化处理

    //配置 Redis, 这个配置的作用主要是使得保存在 redis 里的key和value转换为如图所示的具有可读性的字符串,否则会是乱码,很不便于观察。
    @Configuration
    //Redis 缓存配置类
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            // 创建 RedisTemplate 对象
            RedisTemplate<String, Object> template = new RedisTemplate<>();
            // 设置连接工厂
            template.setConnectionFactory(connectionFactory);
            // 创建 JSON 序列化工具
            GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
            // 设置 key 的序列化
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
            // 设置 value 的序列化
            template.setValueSerializer(jsonRedisSerializer);
            template.setHashValueSerializer(jsonRedisSerializer);
            // 返回
            return template;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    (4)在不使用注解的情况实现redis和mysql的增删改查

    (5)多线程测试redis并发问题
    想要实现的效果就是第一次查询数据的时候是从数据库查询,但是以后的查询都从缓存里查询,在没有上锁的情况,很多数据还没有来得及存到缓存,其他线程就从数据库取数据了。
    在控制层加上多线程

    // http://localhost:8080/redis/findEmpByIdThread/12
    @PostMapping("/redis/findEmpByIdThread/{id}")
    public Object findEmpByIdThread(@PathVariable("id") int id){
        ExecutorService es = Executors.newFixedThreadPool(200);
        for (int i=0;i<500;i++) {
            es.submit(new Runnable() {
                @Override
                public void run() {
                    employeeService.findEmpByIdThread(id);
                }
            });
        }
        Object employee = employeeService.findEmpByIdThread(id);
        return employee;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在业务层加上synchronize锁解决并发问题

    @Override
    public Object findEmpByIdThread(int id) {
        //先从缓存中获取数据,如果有就直接返回
        //如果缓存里没有数据,则查询mysql,并将数据设置到缓存中去
        Object empObj = redisTemplate.opsForValue().get("emp:"+id);
        if(empObj==null){
            synchronized (this.getClass()) {
                empObj = redisTemplate.opsForValue().get("emp:"+id);
                if(empObj==null){
                    //查询数据库
                    System.out.println("——————》查询数据库");
                    EmployeeTemp employee = empMapper.findEmpById02(id);
                    System.out.println(employee);
                    redisTemplate.opsForValue().set("emp:"+id,employee);
                    return employee;
                } else {
                    System.out.println("——————》查询缓存(同步代码块)");
                    return empObj;
                }
            }
    
        } else {
            System.out.println("——————》查询缓存");
        }
        return empObj;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    (6)使用Java注解实现redis的增删改查
    1-重点注意实体类要实现序列化接口才可以,不需要无参构造器

    public class Employee implements Serializable {
        private int id;
        private String name;
    
        public Employee(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2-在service层改成注解的形式

        //增加数据
        @Override
        @Cacheable(value = "employee",key = "'employee-'+#id")
        public Employee findEmpById02(int id) {
            Employee employee = empMapper.findEmpById(id);
            return employee;
        }
    
        @Override
        @CachePut(value = "employee",key = "'employee-'+#employee.getId()")
        public Employee insert02(Employee employee) {
            empMapper.insert01(employee);
            return employee;
        }
    
        @Override
        @CacheEvict(value = "employee",key = "'employee-'+#id")
        public void delete02(int id) {
            empMapper.deleteEmpById(id);
        }
    
        @Override
        @CachePut(value = "employee",key = "'employee-'+#employee.getId()")
        public Employee update02(Employee employee) {
            empMapper.update(employee);
            return employee;
        }
    
        @Override
        @Cacheable(value = "employee",key = "'employee-'+#id")
        public List<Employee> findAll02() {
            List<Employee> employeeList = empMapper.findAll();
            // JSONObject jsonObject = JSONObject.
            return empMapper.findAll();
        }
    
        @Override
        @CacheEvict(allEntries=true)
        public void deleteAll02() {
            empMapper.deleteAll();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
  • 相关阅读:
    什么是指令微调(LLM)
    js之页面列表加载常用方法总结
    安卓BLE开发介绍
    【探花交友】用户登录、代码优化
    python对excel数据表进行数据清洗
    图像上传功能实现
    @WebServlet注解(Servlet注解)
    linux C MD5计算
    OpenCV实现视频的读取、显示、保存
    9. xaml ComboBox控件
  • 原文地址:https://blog.csdn.net/weixin_44823875/article/details/125450944