千家信息网

docker连接spring boot和mysql容器方法介绍

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,在之前使用docker部署运行了Spring Boot的小例子,但是没有使用数据库。在这一篇中,介绍docker如何启动mysql容器,以及如何将Spring Boot容器与mysql容器连接起来运行
千家信息网最后更新 2025年01月23日docker连接spring boot和mysql容器方法介绍

在之前使用docker部署运行了Spring Boot的小例子,但是没有使用数据库。在这一篇中,介绍docker如何启动mysql容器,以及如何将Spring Boot容器与mysql容器连接起来运行。

docker基本命令

首先熟悉一下在操作过程中常用的docker基本命令:

docker images:列出所有docker镜像docker ps:列出所有运行中的容器,-a参数可以列出所有容器,包括停止的docker stop container_id:停止容器docker start container_name:启动已被停止的容器docker rm container_id:删除已经停止的容器,加-f选项可以强制删除正在运行的容器docker rmi image_id:删除镜像,前提是该镜像没有对应的容器docker运行mysql容器

首先是新建Dockerfile:

FROM ubuntu:14.04MAINTAINER loveqhRUN apt-get updateRUN apt-get -y install mysql-serverRUN /etc/init.d/mysql start \  && mysql -uroot -e "grant all privileges on *.* to 'root'@'%' identified by '123456';" \  && mysql -uroot -e "grant all privileges on *.* to 'root'@'localhost' identified by '123456';" RUN sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/my.cnf \  && echo 'skip-host-cache\nskip-name-resolve' | awk '{ print } $1 == "[mysqld]" && c == 0 { c = 1; system("cat") }' /etc/mysql/my.cnf > /tmp/my.cnf \  && mv /tmp/my.cnf /etc/mysql/my.cnfEXPOSE 3306 CMD ["/usr/bin/mysqld_safe"]

然后创建mysql镜像:

docker build -t loveqh/mysql .

下一步便是由该镜像启动一个容器:

docker run -d -P --name docker-mysql loveqh/mysql

其中,

-d表示在后台运行容器,并会返回容器id
-P是将容器所有暴露的端口映射到主机的随机端口号上,也可以使用-p是指定一容器端口的映射关系,如-p 33060:3306,就是把容器的3306端口映射到宿主机的33060端口上

可以通过docker ps查看容器端口映射关系,在PORTS那一列显示

0.0.0.0:32770->3306/tcp

也就是mysql映射到了宿主机的32770端口上了,那么就可以通过

mysql -h 0.0.0.0 -P 32770 -uroot -p

连接到mysql容器了。

docker连接spring boot和mysql容器

之前的文章中已经在docker中运行了Spring Boot的实例,但是没有用到数据库。接下来我们在项目基础上添加数据库操作。
首先在resources下新建application.properties文件来配置数据库:

spring.datasource.url = jdbc:mysql://localhost:3306/springspring.datasource.username = rootspring.datasource.password = 123456spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver

注:这里的url会在稍后连接mysql容器后进行修改。

新建 schema.sql文件,Spring Boot在启动时会自动执行该文件,因此可以在该文件里创建数据表和插入测试数据等操作:

use spring;create table if NOT EXISTS user (  id int PRIMARY KEY NOT NULL auto_increment,  name VARCHAR(30),  password VARCHAR(10),  email VARCHAR(30));-- INSERT INTO user(name, password, email) values("test", "001", "test@163.com");INSERT INTO user(name, password, email)SELECT * FROM (SELECT "test", "001", "test@163.com") AS tmpWHERE NOT EXISTS (  SELECT name FROM user WHERE name='test' AND email='test@163.com') limit 1;

在该文件里,指定了所使用的数据库spring,然后如果没有user表则新建。接下来插入测试数据时,注释了简单的插入命令,因为这样会在每次启动项目时都会插入一条相同的记录,因此用下面的语句代替。

按照之前的步骤创建Spring Boot镜像:

docker build -t loveqh/spring-boot-mysql-docker .

下面是连接运行Spring Boot容器并连接到mysql数据库:

docker run -d -p 8088:8080 -name spring-web -link docker-mysql:mysql loveqh/spring-boot-mysql-docker

其中,

-d仍然是在后台运行,如何不想后台运行,可以将-d参数替换为-it,这样可以看到项目的输出信息。当然,也可以通过docker logs container-name/container-id查看容器日志。
-p参数将容器中Spring Boot默认的8080端口映射到了宿主机的8088端口
-name指定了容器的名字,这样在容器停止后可以通过docker start spring-web重启
-link参数连接到了docker-mysql容器,并使用了别名mysql

刚开始一直纠结spring boot项目如何配置mysql地址,因为在运行mysql容器时没有指定端口映射,是随机映射的,并且如果我们在mysql的url中写localhost:映射端口的话,那么我们使用link连接这两个容器的作用也就没有了。终于在看了一些资料后突然醒悟了,使用-link之后,docker会在子容器(这里的spring boot容器)的/etc/hosts中将父容器(这里的mysql容器)与父容器的ip地址绑定,那么我们就可以mysql:3306来访问数据库了。也就是把application.properties中数据库url改为:

spring.datasource.url = jdbc:mysql://mysql:3306/spring

第二个mysql是我们之前设置的别名。

接下来访问http://localhost:8088就可以看到运行结果了。

项目代码

因为本文主要是讲docker连接两个容器的,因此没有对代码进行说明,下面只是简单地粘贴出关键代码。

Index - 首页name:password:email:

//UserController.javapackage com.xxx;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import java.util.List;/** * Created by wangl on 17-5-16. */@Controller@RequestMapping("/user")public class UserController {  @Autowired  private UserDao userDao;  @RequestMapping(method = RequestMethod.GET)  public String index(Model model) {    model.addAttribute("user", new User());    return "index";  }  @RequestMapping("/list")  public String list(Model model) {    Listusers = userDao.findAll();    model.addAttribute("users", users);    return "list";  }  @RequestMapping(value = "/registry", method = RequestMethod.POST)  public String registry(@ModelAttribute(value = "user") User user, Model model) {    boolean flag = userDao.save(user);    if(flag) {      Listusers = userDao.findAll();      model.addAttribute("users", users);      return "list";    }    model.addAttribute("info", "注册失败!");    return "fail";  }}
//UserDao.javapackage com.xxx;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.stereotype.Repository;import java.util.List;/** * Created by wangl on 17-5-16. */@Repositorypublic class UserDao {  @Autowired  private JdbcTemplate jdbcTemplate;  public ListfindAll() {    String sql = "select id, name, email from user";    RowMappermapper = (rs, rowNum) -> {      User user = new User();      user.setId(rs.getLong(1));      user.setName(rs.getString(2));      user.setEmail(rs.getString(3));      return user;    };    return jdbcTemplate.query(sql, mapper);  }  public boolean save(User user) {    boolean exists = exists(user);    if(exists) {      return false;    }    String sql = "insert into user(name, password, email) values(?, ?, ?)";    int count = jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getEmail());    return count == 1;  }  public boolean exists(User user) {    String sql = "select count(*) from user where name=?";    int count = jdbcTemplate.queryForObject(sql, new Object[]{user.getName()},int.class);    return count != 0;  }}
list - 用户列表  id      name    email   stat:index      stat:count      stat:size       stat:current    stat:even       stat:odd        stat:first      stat:last  id,error        name,error      email,error     error   error   error   error   error   error   error   error 

问题记录

在做的过程中遇到了很多问题,经过查资料解决了,现在将其记录下来。

在使用thymeleaf模板引擎时遇到报错:org.xml.sax.SAXParseException: The element type "THYMELEAF_ROOT" must be terminated by the matching end-tag

之前遇到很多thymeleaf报错,都是html标签的闭合问题,仔细检查html文件中标签是否都闭合以及是否对应
在访问index的注册页面时,遇到报错:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute

这里使用了thymeleaf自动绑定表单进行提交,花了好长时间去检查registry方法和index.html,结果怎么改都出错。后来才发现,原来index页面中有th:object="${user}",但是刚开始index方法并没有在model中添加该对象,因此会出现不能获得user的错误。解决办法就是在所有返回index的方法中,都对model添加user对象:

model.addAttribute("user", new User());

总结

以上就是本文关于docker连接spring boot和mysql容器方法介绍的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:浅谈Docker安全机制内核安全与容器之间的网络安全、详解Docker使用Linux iptables 和 Interfaces管理容器网络、Windows使用docker打开新窗口error解决办法等,有什么问题可以随时留言,小编会及时回复大家的。这里推荐几本学习docker的相关书籍,供广大docker爱好者学习参考:

第一本Docker书 带书签目录 完整pdf扫描版

https://www.jb51.net/books/514869.html

Docker容器与容器云(第2版) 完整pdf扫描版

https://www.jb51.net/books/569549.html

希望大家喜欢!

容器 运行 数据 端口 数据库 文件 镜像 项目 方法 参数 可以通过 问题 安全 接下来 代码 后台 命令 宿主 宿主机 就是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 lol 扭曲丛林服务器 数据库可以用循环语句吗 枣庄高校党建软件开发电话 查数据库数据总条数 创建数据库文件 部队手机网络安全讨论题 配置mysql服务器时 美国软件开发女孩天才 计算机三级数据库考试真题 因服务器频道数据传输异常以断线 软件开发游戏制作培训机构 河南计算机网络技术单招试题 网络技术和软件应用技术区别 ftp由于代理服务器设置 天龙无法打开服务器列表 都江堰市网络技术专业 保险公司软件开发前景 对网络技术工程师的认识 加强网络安全措施和 sql数据库字段长度 如何查询不同数据库中基因的编码 珠海无限软件开发定做价格 信息网络安全处置流程 北栀服务器 中美科技与互联网 网络技术和软件哪个好就业 驻马店市青果网络技术有限公司 网络服务器硬盘多少年换一个 维护网络安全的主要挑战 网络安全信息产业人才发展报告
0