IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【redis-01】redis整合springboot实现简单的增删改查 -> 正文阅读

[Java知识库]【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>

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

(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;
    }
}

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();
}

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;
    }

}

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);
    }
}

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

(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;
    }
}

(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;
}

在业务层加上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;
}

(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;
    }
}

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();
    }
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 17:56:45  更:2022-06-25 17:57:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 17:16:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码