如何基於 Docker 快速搭建 Springboot + Mysql + Redis 專案

秦懷雜貨店發表於2021-12-17

[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兩個容器在跑了:

image-20211121194442579

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:

image-20211121215506343

我們更新一下所有的使用者年齡,呼叫http://localhost:8081/update,返回1

image-20211121215721110

再次訪問http://localhost:8081/getUserList,可以看到年齡全部都變成12:

image-20211121215814253

怎麼知道Redis生效了呢?最好就是debug,或者直接看控制檯,我們已經開啟了debug級別的日誌:

image-20211121220647743

還有一種方式,下載Redis-desktop-manager,可以直接視覺化檢視:

image-20211121221927400

至此,一個demo專案就完成了,可以每次copy出來初始化使用。

【作者簡介】
秦懷,公眾號【秦懷雜貨店】作者,技術之路不在一時,山高水長,縱使緩慢,馳而不息。個人寫作方向:Java原始碼解析JDBCMybatisSpringredis分散式劍指OfferLeetCode等,認真寫好每一篇文章,不喜歡標題黨,不喜歡花裡胡哨,大多寫系列文章,不能保證我寫的都完全正確,但是我保證所寫的均經過實踐或者查詢資料。遺漏或者錯誤之處,還望指正。

劍指Offer全部題解PDF

2020年我寫了什麼?

開源程式設計筆記

相關文章