Springboot Docker Redis Mysql集成

尽管网上关于Springboot Docker Redis Mysql集成的文档很多,但是很多都是老文档,问题不少,所以我专门整理了这份文档。

我家里的笔记本是mac,所以我就在mac上详细说明下我的搭建过程。

首先我们需要安装docker,mac上本来就有docker的安装包,因此对于mac来说,安装docker就是一件比较轻松的事情。

百度搜索docker desktop,然后下载安装docker desktop

安装后的prefercence界面如下:

Springboot Docker Redis Mysql集成

 

为什么我要截这张图,主要是为了从阿里云下载镜像而不是从官网下载,我们可以修改Docker Engine标签里面的json串,

增加一个新的registry-mirrors。当然你也可以通过命令修改,在~/.docker/下有config.json,daemon.json两个文件,你可以修改daemon.json。

安装完docker以后,我们可以下载镜像,当然如果是学习,尽量用最新的,当然你也可能会碰到各种各样的问题了,哈哈!

 

$ docker search mysql

NAME DESCRIPTION STARS OFFICIAL AUTOMATED

mysql MySQL is a widely used, open-source relation… 10014 [OK]

mariadb MariaDB is a community-developed fork of MyS… 3666 [OK]

mysql/mysql-server Optimized MySQL Server Docker images. Create… 733 [OK]

percona Percona Server is a fork of the MySQL relati… 511 [OK]

 

$ docker pull mysql

$ docker search redis

songrongbin$ docker search redis

NAME DESCRIPTION STARS OFFICIAL AUTOMATED

redis Redis is an open source key-value store that… 8616 [OK]

bitnami/redis Bitnami Redis Docker Image 162 [OK]

sameersbn/redis 81 [OK]

grokzen/redis-cluster Redis cluster 3.0, 3.2, 4.0, 5.0, 6.0 71

rediscommander/redis-commander Alpine image for redis-commander - Redis man… 47 [OK]

$ docker pull redis

 

查看下载的镜像:

songrongbin$ docker images

REPOSITORY TAG IMAGE ID CREATED SIZE

spring-boot 1.0-SNAPSHOT b341ae4712c7 23 hours ago 150MB

<none> <none> c74505875f93 24 hours ago 150MB

redis latest 1319b1eaa0b7 8 weeks ago 104MB

mysql latest 0d64f46acfd1 8 weeks ago 544MB

registry latest 2d4f4b5309b1 3 months ago 26.2MB

 

下载好镜像以后然后就需要运行容器了,redis还比较简单没有什么问题,主要就是mysql了,一会我会说详细说下。

docker run -p 6379:6379 -d redis:latest redis-server // 启动redis容器

docker ps //查看容器是否运行

docker exec -it 8266f1466e68 redis-cli //进入容器,并使用运行redis客户端命令

这样redis就启起来了,是不是超级简单,比起以前在linux上安装确实简单多了。

接下来我们启动mysql docker镜像,因为我下载的最新mysql镜像是mysql8,它的dirverclass发生了变化,需要特别注意。

在玩mysql中我们经常会碰到乱码,因为我们在自动容器的时候,就一次性处理这个问题。

docker run -p 3306:3306 --name mysql8 -v /Users/songrongbin/dockerworkspace/data:/data -e LANG=C.UTF-8 -d mysql

docker exec -it mysql env LANG=C.UTF-8 /bin/bash

mysql -uroot -p123456

这样mysql也就起来了

songrongbin$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

8266f1466e68 redis:latest "docker-entrypoint.s…" 21 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp hopeful_bhabha

e8975f945f5f mysql "docker-entrypoint.s…" 2 weeks ago Up 5 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql8

 

看起来很简单,其实为了解决字符集我花费了很长时间,一个是数据库乱码,一个是客户端命令乱码,我们是启动mysql的时候,设置好字符集,就完全避免了各种各样的乱码问题。

 

OK,我们依赖的基础环境就好了,接下来我们就可以专心敲代码了。

创建新项目我还是喜欢在使用https://start.spring.io/,我们创建一个springboot项目后,然后再导入这个项目。

首先我先贴入pom.xml文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

 

<groupId>com.bins</groupId>

<artifactId>spring-boot</artifactId>

<version>1.0-SNAPSHOT</version>

 

<name>spring-boot</name>

<description>Demo project for Spring WebMvc</description>

 

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.3.3.RELEASE</version>

<relativePath />

</parent>

 

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>

</properties>

 

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

</dependency>

 

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

 

<dependency>

<groupId>org.springframework.kafka</groupId>

<artifactId>spring-kafka</artifactId>

</dependency>

 

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>8.0.21</version>

</dependency>

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid-spring-boot-starter</artifactId>

<version>1.1.9</version>

</dependency>

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>2.1.0</version>

</dependency>

<dependency>

<groupId>com.google.guava</groupId>

<artifactId>guava</artifactId>

<version>18.0</version>

</dependency>

<!-- json-schema-validator -->

<dependency>

<groupId>com.github.fge</groupId>

<artifactId>json-schema-validator</artifactId>

<version>2.2.6</version>

</dependency>

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>

 

<!-- mybatis 自动生成 -->

<dependency>

<groupId>org.mybatis.generator</groupId>

<artifactId>mybatis-generator-maven-plugin</artifactId>

<version>1.3.2</version>

</dependency>

 

</dependencies>

 

<build>

<finalName>springboot</finalName>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

<plugin>

<groupId>com.spotify</groupId>

<artifactId>dockerfile-maven-plugin</artifactId>

<version>1.4.9</version>

<configuration>

<repository>${project.artifactId}</repository>

<tag>${project.version}</tag>

</configuration>

</plugin>

<plugin>

<groupId>org.mybatis.generator</groupId>

<artifactId>mybatis-generator-maven-plugin</artifactId>

<version>1.3.2</version>

<configuration>

<configurationFile>src/main/resources/mybatis-generator/generatorConfig.xml</configurationFile>

<verbose>true</verbose>

<overwrite>true</overwrite>

</configuration>

<!-- <executions> <execution> <id>Generate MyBatis Artifacts</id> <goals>

<goal>generate</goal> </goals> </execution> </executions> -->

<dependencies>

<dependency>

<groupId>org.mybatis.generator</groupId>

<artifactId>mybatis-generator-core</artifactId>

<version>1.3.2</version>

</dependency>

</dependencies>

</plugin>

</plugins>

</build>

<reporting>

<plugins>

<plugin>

<groupId>org.codehaus.mojo</groupId>

<artifactId>cobertura-maven-plugin</artifactId>

<version>2.5.1</version>

</plugin>

</plugins>

</reporting>

 

</project>

 

pom.xml文件中有我其他的玩的东西,我也就不删除了,你们觉得没用,删了就行。

接下来就是我们的配置文件了,话说我还是喜欢properties,不喜欢yml,不过这个项目我使用的是yml。

spring:

datasource:

type: com.alibaba.druid.pool.DruidDataSource

url: jdbc:mysql://127.0.0.1:3306/springboot_db?useUnicode=true&characterEncoding=UTF8

driver-class-name: com.mysql.cj.jdbc.Driver

username: root

password: 123456

kafka:

bootstrap-servers: 192.168.10.4:9092

listener:

concurrency: 10

ack-mode: MANUAL_IMMEDIATE

poll-timeout: 1500

consumer:

group-id: logSystem

enable-auto-commit: false

key-deserializer: org.apache.kafka.common.serialization.StringDeserializer

value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

properties: {session.timeout.ms: 6000, auto.offset.reset: earliest}

producer:

key-serializer: org.apache.kafka.common.serialization.StringSerializer

value-serializer: org.apache.kafka.common.serialization.StringSerializer

batch-size: 65536

buffer-memory: 524288

redis:

database: 0

host: 127.0.0.1

port: 6379

password:

jedis:

pool:

max-active: 8

max-wait: -1

max-idle: 8

min-idle: 0

timeout: 1200

log:

df-kafkaconsumer:

topic : dflog

 

logging:

file: /Users/songrongbin/logs/springboot.log

mybatis.config-location: classpath:mybatis-config.xml

这里需要说明的是,mysql8的driverclassname已经变成com.mysql.cj.jdbc.Driver。

然后我贴一些主要的代码,其余的看我git仓库。

 

RedisConfig

 

@Configuration

@EnableCaching

public class RedisConfig {

 

@Bean

public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

RedisTemplate<String, Object> template = new RedisTemplate<>();

template.setConnectionFactory(factory);

Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<Object>(Object.class);

template.setValueSerializer(jacksonSeial);

ObjectMapper objectMapper = new ObjectMapper();

jacksonSeial.setObjectMapper(objectMapper);

// 去掉各种@JsonSerialize注解的解析

objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);

// 只针对非空的值进行序列化

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

// 访问类型

objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

// 对于找不到匹配属性的时候忽略报错

objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

 

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

// 不包含任何属性的bean也不报错

objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

// java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.bins.springboot.pojo.model.User

template.setKeySerializer(new StringRedisSerializer());

template.setHashKeySerializer(new StringRedisSerializer());

template.setHashValueSerializer(jacksonSeial);

template.afterPropertiesSet();

return template;

}

 

@Bean

public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {

return redisTemplate.opsForHash();

}

 

@Bean

public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {

return redisTemplate.opsForValue();

}

 

@Bean

public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {

return redisTemplate.opsForList();

}

 

@Bean

public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {

return redisTemplate.opsForSet();

}

 

@Bean

public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {

return redisTemplate.opsForZSet();

}

 

}

 

这个类需要说明的是:objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

现在很多资料中还是用的om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

但是在springboot2.3.3.RELEASE中,它已经过时了,已经换成文中的用法了,请特别注意。

 

以后在文章里面再完善吧,所有的代码已经上传到https://gitee.com/weitinting/springboot-integration,学习的可以参考下