本文在 “ Docker基础知识 (7) - 使用 Docker 部署 SpringBoot 项目 ” 里的 SpringbootWebDocker 项目的基础上,添加 JDBC、MariaDB 和 MyBatis 相关依赖包和数据库操作代码,并使用 Docker 部署 MariaDB(MySQL)。
1. 部署 MariaDB(MySQL)
1) 部署环境
IP 地址(本地测试环境):192.168.0.10
操作系统:Linux CentOS 7.9
Docker 版本: 20.10.7
注:CentOS 7.9 下不需要安装 Java 环境。
2) 拉取 MariaDB 镜像
$ sudo docker pull mariadb:10.4
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mariadb 10.4 0552982c09ae 7 days ago 404MB
java 8 d23bdf5b1b1b 5 years ago 643MB
...
注:可以访问 Dockers Hub(https://hub.docker.com/_/mariadb?tab=tags)查询 MariaDB 镜像,本文使用 MariaDB 10.4。
3) 配置 MariaDB
在 Docker 所在的主机上创建 MariaDB 相关目录。
$ sudo mkdir -p /home/mysql/{data,conf,log}
data 目录保存数据文件,conf 目录保存配置文件,log 目录保存日志文件。
创建 MariaDB 配置文件:
$ sudo vim /home/mysql/conf/my.conf
# The MySQL server default-character-set=utf8mb4 [mysqld] server-id=1 port=3306 #basedir=/usr/local/mysql #tmpdir=/tmp datadir=/var/lib/mysql log-error=/var/log/mysqld.log #plugin_dir=/usr/local/mysql/lib/plugin/ socket=/var/lib/mysql/mysql.sock pid_file=/var/run/mysqld/mysqld.pid max_connections=400 max_connect_errors=1000 max_allowed_packet=16M # Change here for bind listening # bind-address="127.0.0.1" # bind-address = ::1 # for ipv6 bind-address=0.0.0.0 ## UTF 8 Settings #init-connect=\'SET NAMES utf8\' character-set-server=utf8mb4 collation-server=utf8mb4_general_ci
4) 运行 MariaDB 容器
$ sudo docker run --name mariadb-10.4 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456\
-v /home/mysql/conf/my.conf:/etc/mysql/my.conf\
-v /home/mysql/data:/var/lib/mysql\
-v /home/mysql/log/mysqld.log:/var/log/mysqld.log\
-d mariadb:10.4
参数说明:
-p 3306:3306:映射容器服务的 3306 端口到宿主机的 3306 端口。外部可以直接通过宿主机 ip:3306 访问到 mariadb 的服务。
MYSQL_ROOT_PASSWORD=123456:设置 mariadb 服务 root 用户的密码。
$ sudo docker ps # 查看运行的容器列表
CONTAINER ID IMAGE COMMAND PORTS NAMES
1a424e905075 mariadb:10.4 "docker-entrypoint.s…" 0.0.0.0:3306->3306/tcp mariadb-10.4
...
$ sudo docker exec -it mariadb-10.4 /bin/bash
root@1a424e905075:/# mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8 Server version: 10.4.26-MariaDB-1:10.4.26+maria~ubu2004 mariadb.org binary distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ 3 rows in set (0.001 sec) MariaDB [(none)]>
4) 使用 PhpMyAdmin 远程连接 MariaDB
本文使用 XAMPP for Windows 7.4.25 (https://www.apachefriends.org/download.html)自带的 Apache 2.4 + phpMyAdmin 5.1,修改 Xampp\phpMyAdmin\config.inc.php 文件。
/* Bind to the localhost ipv4 address and tcp */
//$cfg['Servers'][$i]['host'] = '127.0.0.1';
$cfg['Servers'][$i]['host'] = '192.168.0.10';
...
启动 XAMPP 的 Apache,浏览器访问 http://localhost/phpmyadmin,操作数据库。
创建数据库 testdb 和 user 表,SQL 脚本如下:
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, `createtime` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 修改 SpringbootWebDocker 项目
1) 导入 JDBC、MariaDB、MyBatis 等相关依赖包
访问 http://www.mvnrepository.com/ 查询依赖包。
修改 pom.xml:
1 <project ... > 2 ... 3 4 <dependencies> 5 ... 6 7 <dependency> 8 <groupId>org.mariadb.jdbc</groupId> 9 <artifactId>mariadb-java-client</artifactId> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-data-jdbc</artifactId> 14 </dependency> 15 <dependency> 16 <groupId>org.mybatis.spring.boot</groupId> 17 <artifactId>mybatis-spring-boot-starter</artifactId> 18 <version>2.2.0</version> 19 </dependency> 20 21 <dependency> 22 <groupId>org.projectlombok</groupId> 23 <artifactId>lombok</artifactId> 24 <version>1.18.8</version> 25 </dependency> 26 27 ... 28 </dependencies> 29 30 ... 31 </project>
注:lombok 提供了一些简化实体类定义的注解。要使用 lombok,IDEA 需要安装 lombok 插件,这里以 Windows 版的 IDEA 为例,安装步骤如下:
菜单 File -> Settings -> 选中左侧 Plugin -> 搜索 "lombok" -> Install lombok plugin -> Restart IDEA
在 IDE 中项目列表 -> SpringbootWebDocker -> 点击鼠标右键 -> Maven -> Reload Project
2) 修改 src/main/resources/application.properties 文件
spring.main.banner-mode=off # Web server server.display-name=SpringBootWebDocker-Test #server.address=localhost server.port=9090 # Data source spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://192.168.0.10:3306/testdb spring.datasource.driver-class-name=org.mariadb.jdbc.Driver mybatis.mapper-locations=classpath:mapper/*.xml
注:不要设置 server.address。
3) 实体类、配置 MyBatis
(1) 创建 src/main/java/com/example/entity/User.java 文件
1 package com.example.entity; 2 3 import java.util.Date; 4 import java.io.Serializable; 5 6 import lombok.Data; 7 import lombok.NoArgsConstructor; 8 import lombok.experimental.Accessors; 9 10 @NoArgsConstructor // 无参构造函数 11 @Data // 提供类的 get、set、equals、hashCode、canEqual、toString 方法 12 @Accessors(chain = true) 13 public class User implements Serializable { 14 private Integer id; 15 private String username; 16 private String password; 17 private Integer age; 18 private Date createtime; 19 20 }
(2) 创建 src/main/java/com/example/mapper/UserMapper.java 文件
1 package com.example.mapper; 2 3 import org.apache.ibatis.annotations.Mapper; 4 5 import com.example.entity.User; 6 7 @Mapper 8 public interface UserMapper { 9 int insert(User user); 10 User selectByUsername(String username); 11 }
当 mapper 接口较多时,可以在 Spring Boot 主启动类上使用 @MapperScan 注解扫描指定包下的 mapper 接口,而不再需要在每个 mapper 接口上都标注 @Mapper 注解。
(3) 创建 src/main/resources/mapper/UserMapper.xml 文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 <mapper namespace="com.example.mapper.UserMapper"> 5 <resultMap id="BaseResultMap" type="com.example.entity.User"> 6 <id column="id" jdbcType="BIGINT" property="id"/> 7 <result column="username" jdbcType="VARCHAR" property="username"/> 8 <result column="password" jdbcType="VARCHAR" property="password"/> 9 <result column="age" jdbcType="INTEGER" property="age"/> 10 <result column="createtime" jdbcType="DATE" property="createtime"/> 11 </resultMap> 12 <sql id="Base_Column_List"> 13 id, username, password, age, createtime 14 </sql> 15 <insert id="insert" parameterType="com.example.entity.User"> 16 INSERT INTO user (id, username, password, age, createtime) 17 VALUES (#{id,jdbcType=BIGINT}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 18 #{age,jdbcType=INTEGER}, #{createtime,jdbcType=DATE}) 19 </insert> 20 <select id="selectByUsername" parameterType="java.lang.String" resultMap="BaseResultMap"> 21 SELECT 22 <include refid="Base_Column_List"/> 23 FROM user 24 WHERE username = #{username,jdbcType=VARCHAR} 25 </select> 26 </mapper>
4) 服务和控制
(1) 创建 src/main/java/com/example/service/UserService.java 文件
1 package com.example.service; 2 3 import com.example.entity.User; 4 5 public interface UserService { 6 7 int insert(User user); 8 User selectByUsername(String username); 9 10 }
(2) 创建 src/main/java/com/example/service/UserServiceImpl.java 文件
1 package com.example.service; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Service; 5 6 import com.example.entity.User; 7 import com.example.mapper.UserMapper; 8 9 @Service("userService") 10 public class UserServiceImpl implements UserService { 11 @Autowired 12 UserMapper UserMapper; 13 14 @Override 15 public int insert(User user) { 16 return UserMapper.insert(user); 17 } 18 19 @Override 20 public User selectByUsername(String username) { 21 return UserMapper.selectByUsername(username); 22 } 23 24 }
(3) 创建 src/main/java/com/example/controller/UserController.java 文件
1 package com.example.controller; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.web.bind.annotation.RestController; 5 import org.springframework.web.bind.annotation.RequestParam; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 8 import com.example.entity.User; 9 import com.example.service.UserService; 10 11 @RestController 12 public class UserController { 13 @Autowired 14 UserService userService; 15 16 @RequestMapping("/hello") 17 public String hello() { 18 return "Hello Page - SpringBoot Web Docker"; 19 } 20 21 @RequestMapping("/create") 22 public String create(String username, String password, Integer age) { 23 24 if ("".equals(username) || "".equals(password)) { 25 return "Invalid username or password."; 26 } 27 28 User user = userService.selectByUsername(username); 29 System.out.println("user = " + user); 30 if (user != null) { 31 return "'" + username + "' exists, please enter a new username."; 32 } 33 34 user = new User(); 35 user.setUsername(username); 36 user.setPassword(password); 37 user.setAge(age); 38 user.setCreatetime(new Date()); 39 Integer ret = userService.insert(user); 40 if (ret <= 0) { 41 return "Failed to create '" + username + "'."; 42 } 43 44 return "Create '" + username + "' successfully."; 45 } 46 47 }
5) Jar 打包
菜单 View -> Tool Windows -> Maven -> SpringbootWebDocker -> Lifecycle -> Clean & Package
jar 包生成在目录 target/ 里
SpringbootWebDocker.jar
SpringbootWebDocker.jar.original
点击 IDEA 底部 Terminal 标签页,执行如下命令。
java -jar target/SpringbootWebDocker.jar
...
Spring boot web project
浏览器访问 http://localhost:9090/create?username=admin&password=123456&age=20,页面显示:
Create 'admin' successfully.
浏览器访问 http://localhost/phpmyadmin,查看数据库 testdb 里表 user 表,内容如下:
id username password age createtime
1 admin 123456 20 2022-09-02 00:00:00
3. 部署 SpringbootWebDocker 项目 Jar 包
1) 部署环境
IP 地址(本地测试环境):192.168.0.10
操作系统:Linux CentOS 7.9
Docker 版本: 20.10.7
注:CentOS 7.9 下不需要安装 Java 环境。
2) 创建 Dockerfile
创建 /home/docker 目录,把 SpringbootWebDocker.jar 和 application.properties 上传到该目录。
创建 /home/docker/logs 文件夹存放日志文件,该路径与 SpringBoot 项目中 logging.file.path 设置的一致。
创建 home/docker/Dockerfile 文件,内容如下:
# 指定基础镜像 FROM java:8 # 维护者 MAINTAINER Tester # 将文件添加到容器中,并更名为 webdocker.jar ADD SpringbootWebDocker.jar /home/docker/webdocker.jar ADD application.properties /home/docker/application.properties # 指定端口,与 SpringBoot 项目配置文件中的端口一致 EXPOSE 9090 # 容器启动时,运行该程序 ENTRYPOINT ["java", "-jar", "/home/docker/webdocker.jar", "--spring.config.location=/home/docker/application.properties"]
3) 构建镜像
$ cd /home/docker
$ sudo docker build -t webdocker .
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE webdocker latest 8b1cd7959abf 14 seconds ago 668MB mariadb 10.4 0552982c09ae 8 days ago 404MB java 8 d23bdf5b1b1b 5 years ago 643MB ...
4) 创建并启动容器
$ sudo docker run -p 9090:9090 --name webdocker\
-v /home/docker/logs:/home/docker/logs\
-v /home/docker/application.properties:/home/docker/application.properties\
-d webdocker
dde73d87638c8516847c68ead5a9de5ff624fb2534f3ef675b5ab9b354c4f56a
$ sudo docker ps # 查看容器
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
dde73d87638c webdocker "java -jar /home/doc…" 0.0.0.0:9090->9090/tcp webdocker
...
$ sudo docker exec -it webdocker /bin/bash # 进入容器
5) 页面访问
浏览器访问 http://192.168.0.10:9090/create?username=user&password=333666&age=30,页面显示:
Create 'user' successfully.
浏览器访问 http://localhost/phpmyadmin,查看数据库 testdb 里表 user 表,内容如下:
id username password age createtime
1 admin 123456 20 2022-09-02 00:00:00
2 user 333666 30 2022-09-02 00:00:00