您好,登錄后才能下訂單哦!
在之前使用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.04 MAINTAINER loveqh RUN apt-get update RUN apt-get -y install mysql-server RUN /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.cnf EXPOSE 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/spring spring.datasource.username = root spring.datasource.password = 123456 spring.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 tmp WHERE 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.java package 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.java package 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. */ @Repository public 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
希望大家喜歡!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。