关于docker:如何基于-Docker-快速搭建-Springboot-Mysql-Redis-项目

2次阅读

共计 17674 个字符,预计需要花费 45 分钟才能阅读完成。

[TOC]

前言

有时候咱们须要疾速启动一些我的项目,然而环境往往折腾了良久,因而弄一个能够重用的疾速搭建的教程,docker几乎就是这方面的神器,Docker 是一个开源的利用容器引擎,让开发者能够打包他们的利用以及依赖包到一个可移植的镜像中,而后公布到任何风行的 Linux 或 Windows 操作系统的机器上,也能够实现虚拟化。

本教程基于的前提条件:

  • 机器曾经装置配置好JDK1.8,并且环境变量曾经配置胜利
  • Maven曾经配置好,IDEA中我的项目应用的默认 Maven 也配置胜利
  • 本地机器装置好Docker
  • 顺便提一句,我用 navicat 作为数据库可视化操作工具

我的项目地址:https://github.com/Damaer/Dem…

我的项目目录

├── src:源代码
|        ├── main
|        |        ├── java
|   |   |     ├── com.aphysia.springbootdemo
|   |   |     |     ├── config:配置
|   |   |     |     |     ├── RedisConfig:redis 配置
|   |   |     |     ├── constant:常量
|   |   |     |     |     ├── RedisConfig:redis 常量
|   |   |     |     ├── controller:控制器
|   |   |     |     ├── mapper:数据库操作接口
|   |   |     |     ├── model:实体类
|   |   |     |     ├── service:逻辑解决层,包含接口以及实现类
|   |   |     |     |        ├── impl:接口实现类
|   |   |     |     ├──util:工具类
|   |   |     |     |        ├── RedisUtil:redis 工具类
|   |   |     |     ├──SpringdemoApplication:启动类
|        |        ├── resource
|   |   |     ├── mapper 数据库操作 sql
|   |   |     ├── application.yml:全局配置类
|   |   |     ├── user.sql: 初始化 mysql
|        ├──    test: 测试类    
├── pom.xml:我的项目 maven 依赖关系

整体的目录如下:

搭建我的项目

1. docker 装置启动 mysql 以及 redis

1.1 装置 mysql

查问 mysql 最新的镜像:

docker search mysql

拉取最新的 mysql 版本

docker pull mysql:latest

启动mysql,用户名root, 明码123456

docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

能够通过docker ps 查看是否装置胜利

% docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS      PORTS                                                  NAMES
574d30f17868   mysql     "docker-entrypoint.s…"   14 months ago   Up 2 days   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-test

1.2 装置 redis

查问 redis 的镜像

docker search redis

拉取 redis 的最新镜像

% docker pull redis:latest
latest: Pulling from library/redis
eff15d958d66: Pull complete 
1aca8391092b: Pull complete 
06e460b3ba1b: Pull complete 
def49df025c0: Pull complete 
646c72a19e83: Pull complete 
db2c789841df: Pull complete 
Digest: sha256:619af14d3a95c30759a1978da1b2ce375504f1af70ff9eea2a8e35febc45d747
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

docker images能够查看咱们装置了哪些镜像, 能够看到其实我之前也装置过 redis 的镜像:

% docker images
REPOSITORY               TAG       IMAGE ID       CREATED         SIZE
redis                    latest    40c68ed3a4d2   3 days ago      113MB
redis                    <none>    84c5f6e03bf0   14 months ago   104MB
mysql                    latest    e1d7dc9731da   14 months ago   544MB
docker/getting-started   latest    1f32459ef038   16 months ago   26.8MB

让咱们启动一下 redis 的容器:

% docker run -itd --name redis-test -p 6379:6379 redis
7267e14faf93a0e416c39eeaaf51705dc4b6dc3507a68733c20a2609ade6dcd6

能够看到 docker 外面当初有 redismysql两个容器在跑了:

2. 初始化数据库

次要是创立数据库以及测试应用的数据表,初始化数据库的语句:

drop database IF EXISTS test;
CREATE DATABASE test;
use test;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT "",
  `age` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES (1, '李四', 11);
INSERT INTO `user` VALUES (2, '王五', 11);

初始化数据如下:

3. 创立我的项目

在 IDEA 中,File –> New –> Project –> Spring Initializr(抉择 JDK 8):

点击Next:

抉择 Web 上面的Spring WebSQL 上面的 JDBC API,MybatisNoSQL下的 Redis, 也能够不选,间接在pom 文件里本人退出即可:

<img src=”https://markdownpicture.oss-cn-qingdao.aliyuncs.com/blog/20211121213058.png” style=”zoom:70%;” />

一路点Next, 最初Finish, 创立好之后,记得更新一下Maven,装置依赖包。

4. 初始化代码

4.1 全局配置文件以及启动类

全局配置文件application.yml

server:
  port: 8081
spring:
  #数据库连贯配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
  redis:
    host: 127.0.0.1     ## redis 所在的服务器 IP
    port: 6379
    ## 明码,我这里没有设置,所以不填
    password:
    ## 设置最大连接数,0 为有限
    pool:
      max-active: 8
      min-idle: 0
      max-idle: 8
      max-wait: -1
#mybatis 的相干配置
mybatis:
  #mapper 配置文件
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.aphysia.spingbootdemo.model
  #开启驼峰命名
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    root: debug

启动类SpringdemoApplication:

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.aphysia.springdemo.mapper")
public class SpringdemoApplication {public static void main(String[] args) {SpringApplication.run(SpringdemoApplication.class, args);
    }

}

4.2 实体类

与数据库中 user 表对应的实体类User.java:

package com.aphysia.springdemo.model;

public class User {
    int id;
    String name;
    int age;

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

    public int getAge() {return age;}

    public void setAge(int age) {this.age = age;}
}

4.3 Redis 工具类

Redis配置类RedisConfig

package com.aphysia.springdemo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class RedisConfig {

    @Autowired
    private RedisTemplate redisTemplate;

    @Bean
    public RedisTemplate redisTemplateInit() {
        // 设置序列化 Key 的实例化对象
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 设置序列化 Value 的实例化对象
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }
}

Redis 常量类 RedisConstant

package com.aphysia.springdemo.constant;

public class RedisConstant {public static String ALL_USER_KEY = "allUser";}

Redis 工具类 RedisUtil:

package com.aphysia.springdemo.util;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;

@Component
public class RedisUtil {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}

    /**
     * 指定缓存生效工夫
     *
     * @param key  键
     * @param time 工夫(秒)
     */
    public boolean expire(String key, long time) {
        try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 依据 key 获取过期工夫
     *
     * @param key 键 不能为 null
     * @return 工夫(秒) 返回 0 代表为永恒无效
     */
    public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断 key 是否存在
     *
     * @param key 键
     * @return true 存在 false 不存在
     */
    public boolean hasKey(String key) {
        try {return redisTemplate.hasKey(key);
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 能够传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);
            } else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }

    //============================String=============================

    /**
     * 一般缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 一般缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true 胜利 false 失败
     */
    public boolean set(String key, Object value) {
        try {redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }

    }

    /**
     * 一般缓存放入并设置工夫
     *
     * @param key   键
     * @param value 值
     * @param time  工夫(秒) time 要大于 0 如果 time 小于等于 0 将设置无限期
     * @return true 胜利 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {set(key, value);
            }
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要减少几(大于 0)
     * @return
     */
    public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递加
     *
     * @param key   键
     * @param delta 要缩小几(小于 0)
     * @return
     */
    public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递加因子必须大于 0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    //================================Map=================================

    /**
     * HashGet
     *
     * @param key  键 不能为 null
     * @param item 项 不能为 null
     * @return 值
     */
    public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取 hashKey 对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 胜利 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置工夫
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 工夫(秒)
     * @return true 胜利 false 失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {expire(key, time);
            }
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张 hash 表中放入数据, 如果不存在将创立
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 胜利 false 失败
     */
    public boolean hset(String key, String item, Object value) {
        try {redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张 hash 表中放入数据, 如果不存在将创立
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  工夫(秒)  留神: 如果已存在的 hash 表有工夫, 这里将会替换原有的工夫
     * @return true 胜利 false 失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {expire(key, time);
            }
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除 hash 表中的值
     *
     * @param key  键 不能为 null
     * @param item 项 能够使多个 不能为 null
     */
    public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断 hash 表中是否有该项的值
     *
     * @param key  键 不能为 null
     * @param item 项 不能为 null
     * @return true 存在 false 不存在
     */
    public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash 递增 如果不存在, 就会创立一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要减少几(大于 0)
     * @return
     */
    public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash 递加
     *
     * @param key  键
     * @param item 项
     * @param by   要缩小记(小于 0)
     * @return
     */
    public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);
    }

    //============================set=============================

    /**
     * 依据 key 获取 Set 中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {e.printStackTrace();
            return null;
        }
    }

    /**
     * 依据 value 从一个 set 中查问, 是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false 不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入 set 缓存
     *
     * @param key    键
     * @param values 值 能够是多个
     * @return 胜利个数
     */
    public long sSet(String key, Object... values) {
        try {return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将 set 数据放入缓存
     *
     * @param key    键
     * @param time   工夫(秒)
     * @param values 值 能够是多个
     * @return 胜利个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) expire(key, time);
            return count;
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取 set 缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为 value 的
     *
     * @param key    键
     * @param values 值 能够是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }
    //===============================list=================================

    /**
     * 获取 list 缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   完结  0 到 - 1 代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取 list 缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {return redisTemplate.opsForList().size(key);
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取 list 中的值
     *
     * @param key   键
     * @param index 索引  index>= 0 时,0 表头,1 第二个元素,顺次类推;index<0 时,-1,表尾,- 2 倒数第二个元素,顺次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {e.printStackTrace();
            return null;
        }
    }

    /**
     * 将 list 放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 将 list 放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  工夫(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) expire(key, time);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 将 list 放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 将 list 放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  工夫(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) expire(key, time);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 依据索引批改 list 中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除 N 个值为 value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {e.printStackTrace();
            return 0;
        }
    }
}

4.4 Mysql 数据库操作

数据库的 sql 文件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.aphysia.springdemo.mapper.UserMapper">
    <select id="getAllUsers" resultType="com.aphysia.springdemo.model.User">
        SELECT * FROM user
    </select>

    <update id="updateUserAge" parameterType="java.lang.Integer">
        update user set age=age+1 where id =#{id}
    </update>
</mapper>

对应的 mapper 接口UserMapper.java

package com.aphysia.springdemo.mapper;

import com.aphysia.springdemo.model.User;

import java.util.List;

public interface UserMapper {List<User> getAllUsers();

    int updateUserAge(Integer id);
}

4.5 Service 层

先定义一个操作 User 的接口类 UserService,蕴含两个办法,查问所有的user 以及更新 user 的年龄:

package com.aphysia.springdemo.service;

import com.aphysia.springdemo.model.User;

import java.util.List;


public interface UserService {public List<User> getAllUsers();

    public void updateUserAge();}

接口实现类 UserServiceImpl 为了证实 Redis 可用,咱们查问所有的用户的时候,退出了 Redis 缓存,优先从 Redis 中加载数据

package com.aphysia.springdemo.service.impl;

import com.aphysia.springdemo.constant.RedisConstant;
import com.aphysia.springdemo.mapper.UserMapper;
import com.aphysia.springdemo.model.User;
import com.aphysia.springdemo.service.UserService;
import com.aphysia.springdemo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    UserMapper userMapper;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public List<User> getAllUsers() {List<User> users = (List<User>) redisUtil.get(RedisConstant.ALL_USER_KEY);
        if(CollectionUtils.isEmpty(users)){users = userMapper.getAllUsers();
            redisUtil.set(RedisConstant.ALL_USER_KEY,users);
        }
        return users;
    }

    @Override
    @Transactional
    public void updateUserAge() {redisUtil.del(RedisConstant.ALL_USER_KEY);
        userMapper.updateUserAge(1);
        userMapper.updateUserAge(2);
    }
}

4.6 Controller 管制层

减少一个测试层TestController:

package com.aphysia.springdemo.controller;

import com.aphysia.springdemo.model.User;
import com.aphysia.springdemo.service.UserService;
import com.aphysia.springdemo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
public class TestController {

    @Autowired
    UserService userService;


    @RequestMapping("/getUserList")
    @ResponseBody
    public List<User> getUserList() {return userService.getAllUsers();
    }

    @RequestMapping("/update")
    @ResponseBody
    public int update() {userService.updateUserAge();
        return 1;
    }
}

4.7 pom 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aphysia</groupId>
    <artifactId>springdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springdemo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--mysql 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

测试

启动我的项目,输出链接:http://localhost:8081/getUser…,能够获取到所有的user:

咱们更新一下所有的用户年龄, 调用http://localhost:8081/update, 返回1

再次拜访http://localhost:8081/getUserList, 能够看到年龄全副都变成12:

怎么晓得 Redis 失效了呢? 最好就是 debug,或者间接看控制台,咱们曾经开启了debug 级别的日志:

还有一种形式,下载Redis-desktop-manager,能够间接可视化查看:

至此,一个 demo 我的项目就实现了,能够每次 copy 进去初始化应用。

【作者简介】
秦怀,公众号【秦怀杂货店 】作者,技术之路不在一时,山高水长,纵使迟缓,驰而不息。集体写作方向:Java 源码解析JDBCMybatisSpringredis 分布式 剑指 OfferLeetCode等,认真写好每一篇文章,不喜爱题目党,不喜爱花里胡哨,大多写系列文章,不能保障我写的都完全正确,然而我保障所写的均通过实际或者查找材料。脱漏或者谬误之处,还望斧正。

剑指 Offer 全副题解 PDF

2020 年我写了什么?

开源编程笔记

正文完
 0