前置文章
Windows VMWare Centos環境下安裝Docker并配置MySqlhttps://blog.csdn.net/u013224722/article/details/148928081
Windows VMWare Centos Docker部署Springboot應用https://blog.csdn.net/u013224722/article/details/148958480
Windows VMWare Centos Docker部署Nginx并配置對Springboot應用的訪問代理https://blog.csdn.net/u013224722/article/details/149007158
一、MySql 建庫建表
1、新建數據庫
? ? ? ? 通過Widnows宿主機安裝的數據庫管理工具“Navicat Premium”連上在VMWare Centos Docker中創建的MySQL數據庫。新建一個數據庫‘duel_db’。
2、新建數據表
新建managers表, 用于系統管理員的登錄。
新建表,用于存儲用戶信息
新建files表, 用于上傳文檔信息的存儲
二、 Springboot應用使用MySql
1、在IDEA中連接數據庫方式參考
查看VMware Centos的ip
在IDEA右側的Database面板新建Data Source
2、Springboot應用配置mybatis
2.1 修改pom.xml
打開pom.xml文件,添加MySQL? mybatis以及注解相關依賴
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.4</version></dependency><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.4.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
pom.xml文件修改Build,用于mybatis自動生成數據表對象以及mapper。?
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.4.2</version><dependencies><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>9.2.0</version></dependency></dependencies><configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><overwrite>true</overwrite><verbose>true</verbose></configuration></plugin></plugins></build>
2.2 修改application.properties?
新增數據庫連接相關屬性,添加mybatis相關設置。
# MySql
spring.datasource.url=jdbc:mysql://192.168.23.134:3306/duel_db?useSSL=false
spring.datasource.username=root
spring.datasource.password=pwd123456
spring.datasource.driver-class-name= com.mysql.cj.jdbc.Driver# Mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
?2.3 創建mybatis相關配置文件
在resources文件夾下新建 generatorConfig.xml文件,并設置model、mapper相關文件的自動存儲目錄。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 引入 application.properties 中的配置(可選) --><properties resource="application.properties"/><!-- 數據庫驅動路徑(如果未通過Maven依賴管理) --><!-- <classPathEntry location="/path/to/mysql-connector-java-8.0.33.jar"/> --><context id="duel_db" targetRuntime="MyBatis3"><!-- 生成的Java文件編碼 --><property name="javaFileEncoding" value="UTF-8"/><!-- 生成的Java文件的注釋 --><commentGenerator><!-- 注釋配置:不生成注釋 --><property name="suppressAllComments" value="true"/><!-- 生成注釋 --><!-- <property name="addRemarkComments" value="true"/>--></commentGenerator><!-- 數據庫連接信息 --><jdbcConnection driverClass="${spring.datasource.driver-class-name}"connectionURL="${spring.datasource.url}"userId="${spring.datasource.username}"password="${spring.datasource.password}"></jdbcConnection><!-- Java模型生成配置 --><javaModelGenerator targetPackage="com.duelapi.model" targetProject="src/main/java"><property name="enableSubPackages" value="true"/><property name="trimStrings" value="true"/></javaModelGenerator><!-- 生成 SQL Map XML 文件的配置 --><sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"><property name="enableSubPackages" value="false"/></sqlMapGenerator><!-- Mapper接口生成配置 --><javaClientGenerator type="XMLMAPPER" targetPackage="com.duelapi.mapper" targetProject="src/main/java"><property name="enableSubPackages" value="false"/></javaClientGenerator><table schema="Local" tableName="files" domainObjectName="FileRecord"enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"enableSelectByExample="false" selectByExampleQueryId="false"></table><table schema="Local" tableName="members" domainObjectName="MemberRecord"enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"enableSelectByExample="false" selectByExampleQueryId="false"></table><table schema="Local" tableName="managers" domainObjectName="ManagerRecord"enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"enableSelectByExample="false" selectByExampleQueryId="false"></table></context>
</generatorConfiguration>
修改啟動類,新增@MapperScan("com.duelapi.mapper")
package com.duelapi;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.duelapi.mapper")
public class DuelApiApplication {public static void main(String[] args) {SpringApplication.run(DuelApiApplication.class, args);}}
2.4 生成Model及Mapper文件?
在右側Maven面板,雙擊 mybatis-generator,自動執行生成操作。
?2.5 新增數據庫查詢語句
ManagerRecordMapper.java、??ManagerRecordMapper.xml中新增查詢管理員的SQL
ManagerRecord selectByAccount(String account);
<select id="selectByAccount" parameterType="java.lang.String" resultMap="BaseResultMap">select<include refid="Base_Column_List" />from managerswhere account = #{account,jdbcType=VARCHAR}</select>
ManagerRecordMapper.java、??ManagerRecordMapper.xml中新增查詢member的SQL?
List<MemberRecord> selectAll();
<select id="selectAll" resultMap="BaseResultMap">select<include refid="Base_Column_List" />from members</select>
?3、新增MySQL交互相關接口
?MemberRecord.java 新增轉鍵值對的方法。
public Map<String, Object> toMap(){Map<String, Object> result = new HashMap<>();result.put("id", this.getId());result.put("memberName", this.getMemberName());result.put("account", this.getAccount());return result;}
? 新建ManageController.java
package com.duelapi.controller;import com.duelapi.model.MemberRecord;
import com.duelapi.service.IManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;import java.util.Map;@Controller
@RequestMapping("/manage")
public class ManageController {private IManageService manageService;@Autowiredpublic ManageController(IManageService manageService){this.manageService = manageService;}@RequestMapping(value = "/managerLogin", method = RequestMethod.GET)@ResponseBodypublic Map<String, Object> managerLogin(@RequestParam(value = "account") String account,@RequestParam(value = "pwd") String pwd) {return this.manageService.managerLogin(account, pwd);}@RequestMapping(value = "/getMemberList", method = RequestMethod.GET)@ResponseBodypublic Map<String, Object> getMemberList() {return this.manageService.getMemberList();}@RequestMapping(value = "/addMember", method = RequestMethod.POST)@ResponseBodypublic Map<String, Object> addMember(@RequestBody MemberRecord memberInfo) {return this.manageService.addMember(memberInfo);}@RequestMapping(value = "/deleteMember", method = RequestMethod.GET)@ResponseBodypublic Map<String, Object> deleteMember(@RequestParam(value = "id") Integer id) {return this.manageService.deleteMember(id);}
}
新建 interface? ?IManageService.java?
package com.duelapi.service;import com.duelapi.model.MemberRecord;import java.util.Map;public interface IManageService {Map<String, Object> managerLogin(String account, String pwd);Map<String, Object> addMember(MemberRecord memberRec);Map<String, Object> deleteMember(Integer id);Map<String, Object> getMemberList();
}
新建?ManageService.java 實現?IManageService.java?
package com.duelapi.serviceimpl;import com.duelapi.mapper.ManagerRecordMapper;
import com.duelapi.mapper.MemberRecordMapper;
import com.duelapi.model.ManagerRecord;
import com.duelapi.model.MemberRecord;
import com.duelapi.service.IManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.*;
import java.util.stream.Collectors;@Service
public class ManageService implements IManageService {private ManagerRecordMapper managerMapper;private MemberRecordMapper memberMapper;@Autowiredpublic ManageService(ManagerRecordMapper managerMapper,MemberRecordMapper memberMapper){this.managerMapper = managerMapper;this.memberMapper = memberMapper;}@Overridepublic Map<String, Object> managerLogin(String account, String pwd) {Map<String, Object> resultMap = new HashMap<>();ManagerRecord rec = this.managerMapper.selectByAccount(account);if(rec != null){if( rec.getPwd().equals(pwd)) {resultMap.put("status", "1");resultMap.put("msg", "success");}else {resultMap.put("status", "0");resultMap.put("msg", "密碼錯誤");}}else{resultMap.put("status", "0");resultMap.put("msg", "管理員賬戶不存在");}return resultMap;}@Overridepublic Map<String, Object> addMember(MemberRecord memberRec) {Map<String, Object> resultMap = new HashMap<>();int nFlag = this.memberMapper.insertSelective(memberRec);if(nFlag == 1){resultMap.put("status", "1");resultMap.put("msg", "success");}else{resultMap.put("status", "0");resultMap.put("msg", "數據保存至數據庫出錯!");}return resultMap;}@Overridepublic Map<String, Object> deleteMember(Integer id) {Map<String, Object> resultMap = new HashMap<>();int nFlag = this.memberMapper.deleteByPrimaryKey(id);if(nFlag == 1){resultMap.put("status", "1");resultMap.put("msg", "success");}else{resultMap.put("status", "0");resultMap.put("msg", "數據庫刪除時出錯!");}return resultMap;}@Overridepublic Map<String, Object> getMemberList() {List<MemberRecord> arrRecords = this.memberMapper.selectAll();List<Map<String, Object>> ltMaps = new ArrayList<>();int nAmount = 0;if (arrRecords != null && !arrRecords.isEmpty()) {ltMaps = arrRecords.stream().map(vo -> vo.toMap()).collect(Collectors.toList());nAmount = arrRecords.size();}Map<String, Object> resultMap = new HashMap<>();resultMap.put("rows", ltMaps);resultMap.put("total", nAmount);return resultMap;}
}
創建完成后的文件目錄如下?
?
啟動測試?
瀏覽器直接訪問接口進行測試,測試通過。
4、前后端分離測試?
1、新建一個H5項目,添加JQuery、bootstrap、bootstrap-table引用
const.js 文件中定義接口訪問地址
constUtils = {Server:"http://localhost:8093/",
};
index.html中實現對接口的調用及測試結果顯示
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>測試</title><link href="./plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet"><link href="./plugins/bootstrap/css/bootstrap-table.min.css" rel="stylesheet">
</head>
<body><div style="max-width: 720px; margin: 30px auto"><div id="tabToolbar"></div><table id="tabMain" data-toolbar="#tabToolbar"></table><div style="margin-top: 40px; background: #e7e7e7; padding: 30px"><h4>新增測試</h4><div style="padding: 20px 0"><label style="display: block"> 姓名:<input type="text" id="txtName"></label><label style="display: block"> 賬號:<input type="text" id="txtAccount"></label><label style="display: block"> 密碼:<input type="password" id="txtPwd"></label></div><button id="btnAddManager" type="button" class="btn btn-primary" onclick="addNewMember()">提交</button></div>
</div><script type="text/javascript" src="js/const.js"></script>
<script type="text/javascript" src="js/jquery.min.js?v2.1.4"></script>
<script src="./plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="./plugins/bootstrap/js/bootstrap-table.min.js"></script><script>$(document).ready(function () {doUpdateTab();});function doUpdateTab() {$('#tabMain').bootstrapTable('destroy');$('#tabMain').bootstrapTable({method: 'get',toolbar: '#tabToolbar', //工具按鈕用哪個容器striped: true, //是否顯示行間隔色cache: false, //是否使用緩存,默認為true,所以一般情況下需要設置一下這個屬性(*)pagination: true, //是否顯示分頁(*)sortable: false, //是否啟用排序sortOrder: "desc", //排序方式pageNumber: 1, //初始化加載第一頁,默認第一頁pageSize: 50, //每頁的記錄行數(*)pageList: [10, 25, 50, 100], //可供選擇的每頁的行數(*)url: constUtils.Server + "manage/getMemberList",//這個接口需要處理bootstrap table傳遞的固定參數queryParamsType: 'undefined', //默認值為 'limit' ,在默認情況下 傳給服務端的參數為:offset,limit,sortqueryParams: function queryParams(queryParams) { //設置查詢參數return {};},//前端調用服務時,會默認傳遞上邊提到的參數,如果需要添加自定義參數,可以自定義一個函數返回請求參數sidePagination: "server", //分頁方式:client客戶端分頁,server服務端分頁(*)search: true, //是否顯示表格搜索,此搜索是客戶端搜索,不會進服務端,所以,個人感覺意義不大strictSearch: false,showColumns: true, //是否顯示所有的列showRefresh: true, //是否顯示刷新按鈕minimumCountColumns: 2, //最少允許的列數clickToSelect: true, //是否啟用點擊選中行searchOnEnterKey: true,columns: [{title: '序號',align: 'center',formatter: function (value, row, index) {return index + 1;}},{field: 'memberName',title: '姓名',searchable: true,align: 'center'},{field: 'account',title: '賬號',searchable: true,align: 'center'},{title: '操作',align: 'center',searchable: false,formatter: function (value, row, index) {return '<a class="btn" style="margin-left: 10px;" ' +' onclick="deleteRecord(\'' + row.id + '\')">刪除</a>';}}],onLoadSuccess: function (data) { //加載成功時執行console.log(data)},onLoadError: function (err) {console.log(err);},showToggle: false, //是否顯示詳細視圖和列表視圖的切換按鈕cardView: false, //是否顯示詳細視圖detailView: false, //是否顯示父子表});}function deleteRecord(id) {$.ajax({method: "GET",url: constUtils.Server + "manage/deleteMember",data: {id:id},cache: false,dataType: "json",contentType: "application/json",async: false, //同步success: function (res) {console.log(res);$('#tabMain').bootstrapTable('refresh');},error: function (err) {console.log(err);}});}function addNewMember(){let memberInfo ={memberName: $('#txtName').val(),account: $('#txtAccount').val(),pwd: $('#txtPwd').val()};console.log(memberInfo);$.ajax({method: "POST",url: constUtils.Server + "manage/addMember",data: JSON.stringify(memberInfo),cache: false,dataType: "json",contentType: "application/json",async: false, //同步success: function (res) {console.log(res);$('#tabMain').bootstrapTable('refresh');},error: function (err) {console.log(err);}});}</script></body>
</html>
瀏覽器中加載H5進行測試
初始運行,Member 列表為空。
填寫Member信息并提交
?提交后,表格中顯示了新增的member,接口實現成功。 正常對MySql進行讀寫。
三、發布至Docker
1、發布jar包并部署至Docker
? ? ? ?Idea 中pom.xml修改version為 0.0.2,將springboot應用打包為 dapi-0.0.2.jar. 我使用的打包方式前置文章中有介紹。 將Jar包拷貝進VMWare Centos系統中。
修改Dockerfile?
#Dockerfile 內容FROM openjdk:24# 后端工作目錄
VOLUME /app# 后端jar包名稱
COPY dapi-0.0.2.jar /app/dapi.jar# 后端項目的端口號
EXPOSE 8093#啟動時指令
ENTRYPOINT ["java", "-jar", "/app/dapi.jar"]
移除Docker中的dapi-0.0.1版本?
duel@localhost:~/workspace$ sudo docker ps -a
duel@localhost:~/workspace$ sudo docker stop dapi
duel@localhost:~/workspace$ sudo docker rm dapi
duel@localhost:~/workspace$ sudo docker ps -a
duel@localhost:~/workspace$ sudo docker images
duel@localhost:~/workspace$ sudo docker rmi dapi:1.0.0
安裝上0.0.2版本?
#執行Image安裝$ sudo docker build -t dapi:0.0.2 .#啟動容器并映射端口$ sudo docker run --name dapi -p 8093:8093 -d dapi:0.0.2 --restart=always
Terminal終端日志如下:?
VMWare Centos 打開Firefox瀏覽器測試接口,成功。
切換Nginx代理的端口號 【38081】,測試成功。我的Nginx的配置可在前置文章中查看
2、發布靜態網頁至Docker
Windows 中 用 Webstorm創建的前端測試H5,拷貝至VMWare Center Os 中
VMWare Centos 系統下存放位置如下:
移除Nginx容器,重新創建Nginx。
Nginx配置方式可參考我的前置文章:
Windows VMWare Centos Docker部署Nginx并配置對Springboot應用的訪問代理-CSDN博客
VMWare Centos 打開Firefox瀏覽器測試接口,成功。
3、Windows宿主機測試
? ? ?回到Windows宿主機,打開Chrome瀏覽器, 通過虛擬機Centos的ip + Docker中配置的Nginx的代理端口號對靜態網頁和接口分別進行測試。
接口訪問成功,靜態網頁訪問成功,網頁調用接口加載數據失敗:
查找原因:localhost 僅在 VMWare Centos 系統內部有效
修改接口地址后,重新發布
測試成功
至此,前后端分類的 Html? + Springboot + mybatis + MySql + Nginx 項目在VMWare Centos Docker中完整實踐完成。
下一篇,繼續實踐 Springboot 處理文件上傳后在Docker中的存儲以及返回 http://upload_file_web_url 相關功能。