基于Springboot+Vue實現(xiàn)的在線答題闖關(guān)系統(tǒng)全過程
前言
本系統(tǒng)采用前后端分離架構(gòu),前端使用Vue.js框架實現(xiàn),后端則通過Spring Boot進(jìn)行構(gòu)建,數(shù)據(jù)存儲使用MySQL數(shù)據(jù)庫。前端使用Vue.js進(jìn)行數(shù)據(jù)渲染,而后端提供RESTful API接口來實現(xiàn)前后端的有效數(shù)據(jù)交互。
項目功能及技術(shù)
功能模塊設(shè)計
順序出題模塊:該模塊允許用戶按順序答題,系統(tǒng)根據(jù)預(yù)設(shè)的題目順序逐一展示給用戶。用戶完成每一道題后可以進(jìn)入下一題,適合需要系統(tǒng)化學(xué)習(xí)的用戶。
體型練習(xí)模塊:用戶可以根據(jù)自己的需求選擇特定的練習(xí)模式,比如選擇某個類別或某個難度的題目進(jìn)行練習(xí)。該模塊支持用戶自定義練習(xí)內(nèi)容,幫助用戶強(qiáng)化薄弱的知識點。
隨機(jī)出題模塊:系統(tǒng)可以隨機(jī)從題庫中抽取題目,進(jìn)行答題闖關(guān),用戶在有限的時間內(nèi)答題,提升學(xué)習(xí)的趣味性和挑戰(zhàn)性。
錯題本模塊:該模塊記錄用戶做錯的題目,用戶可以隨時查看并重新進(jìn)行練習(xí),幫助用戶集中攻克自己的薄弱環(huán)節(jié),提升記憶與掌握度。
我的收藏模塊:用戶可以將自己喜歡或難度較高的題目收藏到個人收藏夾,方便以后再次復(fù)習(xí)或挑戰(zhàn)。
答題統(tǒng)計模塊:系統(tǒng)自動統(tǒng)計用戶的答題情況,包括正確率、答題速度、錯題數(shù)量等,幫助用戶了解自己的學(xué)習(xí)進(jìn)度和成效,并能根據(jù)數(shù)據(jù)調(diào)整學(xué)習(xí)策略。
技術(shù):
Spring Boot:后端框架,利用Spring Boot的快速開發(fā)特性。同時,通過Mybatis簡化數(shù)據(jù)庫操作,提高數(shù)據(jù)訪問效率。
Vue.js:前端框架,使用Vuex進(jìn)行全局狀態(tài)管理,提升數(shù)據(jù)的一致性與可維護(hù)性。
MySQL:數(shù)據(jù)庫存儲引擎,負(fù)責(zé)存儲題目數(shù)據(jù)、用戶答題記錄、錯題與收藏等信息。
Layui:前端UI組件庫,用于搭建美觀且響應(yīng)式的用戶界面,提升用戶交互體驗。
用戶端
管理端
API
SpringBoot框架搭建
1.創(chuàng)建maven project,先創(chuàng)建一個名為SpringBootDemo的項目,選擇【New Project】
然后在彈出的下圖窗口中,選擇左側(cè)菜單的【New Project】
在project下創(chuàng)建module,點擊右鍵選擇【new】—【Module…】
左側(cè)選擇【Spring initializr】,通過idea中集成的Spring initializr工具進(jìn)行spring boot項目的快速創(chuàng)建。窗口右側(cè):name可根據(jù)自己喜好設(shè)置,group和artifact和上面一樣的規(guī)則,其他選項保持默認(rèn)值即可,【next】
Developer Tools模塊勾選【Spring Boot DevTools】,web模塊勾選【Spring Web】,此時,一個Springboot項目已經(jīng)搭建完成,可開發(fā)后續(xù)功能
實體映射創(chuàng)建Mapper
創(chuàng)建一個entity實體類文件夾,并在該文件夾下創(chuàng)建項目用到的實體類
package com.example.demo.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Data public class User { @TableId(type = IdType.AUTO) private Long id; private String account; private String pwd; private String userDesc; private String userHead; private LocalDateTime createTime; private Long role; private String nickname; private String email; private String tags; }
接口封裝
由于我們使用mybatis-plus,所以簡單的增刪改查不用自己寫,框架自帶了,只需要實現(xiàn)或者繼承他的Mapper、Service
創(chuàng)建控制器Controller
整合Swagger
添加依賴
先導(dǎo)入spring boot的web包
<!--swagger依賴--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
配置Swagger
創(chuàng)建一個swagger的配置類,命名為SwaggerConfig.java
/* *用于定義API主界面的信息,比如可以聲明所有的API的總標(biāo)題、描述、版本 */ private ApiInfo apiDemo() { return new ApiInfoBuilder() //用來自定義API的標(biāo)題 .title("SpringBoot項目SwaggerAPIAPI標(biāo)題測試") //用來描述整體的API .description("SpringBoot項目SwaggerAPI描述測試") //創(chuàng)建人信息 .contact(new Contact("測試員張三","http://localhost:8080/springboot/swagger-ui.html","xxxxxxxx@163.com")) //用于定義服務(wù)的域名 //.termsOfServiceUrl("") .version("1.0") //可以用來定義版本 .build(); }
接口測試
運行Spring Boot項目,默認(rèn)端口8080,通過地址欄訪問url
接口組定義
根據(jù)不同的業(yè)務(wù)區(qū)分不同的接口組,使用@API來劃分
@Api(tags = "用戶管理") // tags:組名稱 @RestController public class RoleController { }
接口定義
使用@ApiModel來標(biāo)注實體類,同時在接口中定義入?yún)閷嶓w類作為參數(shù)。
@ApiModel:用來標(biāo)類
常用配置項:value:實體類簡稱;description:實體類說明
@ApiModelProperty:用來描述類的字段的含義。
常用字段類型
字段類型 | 所占字節(jié) | 存儲范圍 | 最大存儲值 | 使用場景 |
---|---|---|---|---|
TINYINT | 1 | -128~127 | 127 | 存儲小整數(shù) |
INT | 4 | -2147483648~2147483647 | 2147483647 | 存儲大整數(shù) |
BIGINT | 8 | -9223372036854775808~9223372036854775807 | 9223372036854775807 | 存儲極大整數(shù) |
DECIMAL | 可變長度 | 存儲精度要求高的數(shù)值 | ||
CHAR | 固定長度 | 最多255字節(jié) | 255個字符 | 存儲長度固定的字符串 |
VARCHAR | 可變長度 | 最多65535字節(jié) | 65535個字符 | 存儲長度不固定的字符串 |
DATETIME | 8 | ‘1000-01-01 00:00:00’~‘9999-12-31 23:59:59’ | ‘9999-12-31 23:59:59’ | 存儲日期和時間 |
參考代碼塊
<body style="background-color: #f7f7f7;"> <div class="headerBox"> <div class="logoBox"> <img src="img/logo1.png" /> <div class="logoTitle">在線答題闖關(guān)</div> </div> <div class="menuBox"> <div class="menuItem activeMenu "> <a href="index.html" rel="external nofollow" rel="external nofollow" >練習(xí)模式</a> </div> <div class="menuItem blackColor"> <a href="challengeLevels.html?param=primary" rel="external nofollow" rel="external nofollow" >闖關(guān)模式</a> </div> <div class="menuItem blackColor"> <a href="wrongQuestion.html" rel="external nofollow" rel="external nofollow" >我的錯題</a> </div> <div class="menuItem blackColor"> <a href="myCollection.html" rel="external nofollow" rel="external nofollow" >我的收藏</a> </div> <div class="menuItem blackColor"> <a href="statistics.html" rel="external nofollow" rel="external nofollow" >答題統(tǒng)計</a> </div> <div class="menuItem blackColor"> <a href="center.html" rel="external nofollow" rel="external nofollow" >個人中心</a> </div> <div class="menuItem blackColor"> <a href="./login/login.html" rel="external nofollow" rel="external nofollow" >退出登錄</a> </div> </div> </div> <div class="container-fluid" id="content-page"> <div class="row"> <div class="col-md-2"> </div> <div class="col-md-8"> <div class="searchBox"> <div class="leftTitle"> {{pageTitle}} </div> </div> </div> <div class="col-md-2"> </div> </div> <div class="row"> <div class="col-md-2"> </div> <div class="col-md-8"> <div v-for="(item,index) in questionList"> <div class="radioItemBox" v-if="item.questionType == '單選題'"> <div class="BtnBox radioItem"> <div>{{index+1}}.</div> <textarea rows="18" cols="90" v-model="item.title" disabled></textarea> <img src="img/collecQues.png" class="radioItemTypeImg" v-on:click="collection(item.id)" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkA!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'A')" /> </div> <div>A.</div> <input v-model="item.checkA" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkB!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'B')" /> </div> <div>B.</div> <input v-model="item.checkB" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkC!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'C')" /> </div> <div>C.</div> <input v-model="item.checkC" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkD!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'D')" /> </div> <div>D.</div> <input v-model="item.checkD" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkE!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'E')" /> </div> <div>E.</div> <input v-model="item.checkE" disabled class="radioLineV2Input" /> </div> </div> <div class="radioItemBox" v-if="item.questionType == '多選題'"> <div class="BtnBox radioItem"> <div>{{index+1}}.</div> <textarea rows="18" cols="90" v-model="item.title" disabled></textarea> <img src="img/collecQues.png" class="radioItemTypeImg" v-on:click="collection(item.id)" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkA!=''"> <div class="radioIconBox"> <input type="checkbox" class="radioInputCheck" :name="index" v-on:change="checkTwo($event,index,'A')" /> </div> <div>A.</div> <input v-model="item.checkA" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkB!=''"> <div class="radioIconBox"> <input type="checkbox" class="radioInputCheck" :name="index" v-on:change="checkTwo($event,index,'B')" /> </div> <div>B.</div> <input v-model="item.checkB" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkC!=''"> <div class="radioIconBox"> <input type="checkbox" class="radioInputCheck" :name="index" v-on:change="checkTwo($event,index,'C')" /> </div> <div>C.</div> <input v-model="item.checkC" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkD!=''"> <div class="radioIconBox"> <input type="checkbox" class="radioInputCheck" :name="index" v-on:change="checkTwo($event,index,'D')" /> </div> <div>D.</div> <input v-model="item.checkD" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkE!=''"> <div class="radioIconBox"> <input type="checkbox" class="radioInputCheck" :name="index" v-on:change="checkTwo($event,index,'E')" /> </div> <div>E.</div> <input v-model="item.checkE" disabled class="radioLineV2Input" /> </div> </div> <div class="radioItemBox" v-if="item.questionType == '判斷題'"> <div class="BtnBox radioItem"> <div>{{index+1}}.</div> <textarea rows="18" cols="90" v-model="item.title" disabled></textarea> <img src="img/collecQues.png" class="radioItemTypeImg" v-on:click="collection(item.id)" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkA!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'A')" /> </div> <div>A.</div> <input v-model="item.checkA" disabled class="radioLineV2Input" /> </div> <div class="BtnBox radioLineV2" v-if="item.checkB!=''"> <div class="radioIconBox"> <input type="radio" class="radioInputCheck" :name="index" v-on:change="checkOne(index,'B')" /> </div> <div>B.</div> <input v-model="item.checkB" disabled class="radioLineV2Input" /> </div> </div> </div> <div class="BtnBox margin-sm"> <div class="AddQuesBtnItem" v-on:click="SaveChange"> <img src="img/submit.png" /> 提交 </div> <div style="height:100px;"></div> </div> </div> <div class="col-md-2"> </div> </div> </div> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript" src="login/layui/layui.js"></script> <script> //輕量級框架 var dataInfo = new Vue({ el: "#content-page", //Vue的數(shù)據(jù)對象 data: { questionList: [], pageTitle: '' }, //數(shù)據(jù)對象結(jié)束 //方法 methods: { GetAll: function() { let vm = this; let param = GetQueryString("param"); let type = GetQueryString("type"); let quesType = ''; if (param == 'practice') { if (type == '0') { quesType = '單選題'; } else if (type == '1') { quesType = '多選題'; } else { quesType = '判斷題'; } vm.pageTitle = '練習(xí)模式:' + quesType; } else if (param == 'order') { vm.pageTitle = '順序出題'; } else { vm.pageTitle = '隨機(jī)練習(xí)'; } var user = JSON.parse(sessionStorage.getItem('user')); $.ajax({ url: "http://127.0.0.1:8081/common/answer-list?userId=" + user.id + "¶m=" + param + "&type=" + quesType, async: false, type: "POST", contentType: 'application/json', dataType: 'json', success: function(json) { vm.questionList = json.list } }); }, //單選框選擇事件 checkOne(index, check) { let vm = this; vm.questionList[index].isChecked = check; }, //多選框選擇事件 checkTwo(event, index, check) { let vm = this; const checked = event.target.checked; let info = vm.questionList[index]; let checkedArray = info.isChecked.split(','); if (checkedArray[0] == '') { checkedArray.splice(0, 1); } if (checked) { checkedArray.push(check); info.isChecked = checkedArray.join(','); } else { let ind = checkedArray.indexOf(check); if (ind !== -1) { checkedArray.splice(ind, 1); } info.isChecked = checkedArray.join(','); } }, //點擊提交 SaveChange() { let vm = this; //得分 let number = 0; let list = vm.questionList; for (let i = 0; i < list.length; i++) { if (list[i].isChecked != '') { let right = list[i].rightKey.split(','); let check = list[i].isChecked.split(','); if (right.length === check.length && right.sort().toString() === check.sort() .toString()) { list[i].correct = 1; number++; } } } var user = JSON.parse(sessionStorage.getItem('user')); var vo = {}; vo.answerList = list; vo.number = number; vo.userId = user.id; vo.type = '練習(xí)'; $.ajax({ url: "http://127.0.0.1:8081/common/get-answer", async: false, type: "POST", contentType: 'application/json', dataType: 'json', data: JSON.stringify(vo), success: function(json) { layui.use('layer', function() { var layer = layui.layer; // 彈出提示框 layer.msg('您的分?jǐn)?shù)為:' + number + '分', { icon: 6, // 圖標(biāo)樣式,默認(rèn)為信息圖標(biāo) time: 2000, // 顯示時間,默認(rèn)為2秒 shade: 0.5, // 遮罩層透明度,默認(rèn)為0.3 shadeClose: true // 是否點擊遮罩關(guān)閉彈框,默認(rèn)為true }); }); } }); }, //點擊收藏 collection(id) { var vo = {}; var user = JSON.parse(sessionStorage.getItem('user')); vo.userId = user.id; vo.answerId = id; $.ajax({ url: "http://127.0.0.1:8081/common/addCollect", async: false, type: "POST", contentType: 'application/json', dataType: 'json', data: JSON.stringify(vo), success: function(json) { layui.use('layer', function() { var layer = layui.layer; // 彈出提示框 layer.msg(json.returnMsg, { icon: json.returnMsg == '您已收藏過' ? 5 : 6, // 圖標(biāo)樣式,默認(rèn)為信息圖標(biāo) time: 2000, // 顯示時間,默認(rèn)為2秒 shade: 0.5, // 遮罩層透明度,默認(rèn)為0.3 shadeClose: true // 是否點擊遮罩關(guān)閉彈框,默認(rèn)為true }); }); } }); }, }, //方法結(jié)束 created: function() { var vm = this; vm.GetAll(); }, //初始加載方法結(jié)束 }); //vue結(jié)束 function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } </script> </body> </html>
<head> <meta charset="utf-8" /> <title>答題統(tǒng)計</title> </head> <link href="css/index.css" rel="external nofollow" rel="stylesheet" /> <link href="css/bootstrap.min.css" rel="external nofollow" rel="stylesheet" /> <body style="background-color: #f7f7f7;"> <div class="headerBox"> <div class="logoBox"> <img src="img/logo1.png" /> <div class="logoTitle">在線答題闖關(guān)</div> </div> <div class="menuBox"> <div class="menuItem blackColor"> <a href="index.html" rel="external nofollow" rel="external nofollow" >練習(xí)模式</a> </div> <div class="menuItem blackColor"> <a href="challengeLevels.html?param=primary" rel="external nofollow" rel="external nofollow" >闖關(guān)模式</a> </div> <div class="menuItem blackColor"> <a href="wrongQuestion.html" rel="external nofollow" rel="external nofollow" >我的錯題</a> </div> <div class="menuItem blackColor"> <a href="myCollection.html" rel="external nofollow" rel="external nofollow" >我的收藏</a> </div> <div class="menuItem activeMenu"> <a href="statistics.html" rel="external nofollow" rel="external nofollow" >答題統(tǒng)計</a> </div> <div class="menuItem blackColor"> <a href="center.html" rel="external nofollow" rel="external nofollow" >個人中心</a> </div> <div class="menuItem blackColor"> <a href="./login/login.html" rel="external nofollow" rel="external nofollow" >退出登錄</a> </div> </div> </div> <div class="container-fluid" id="content-page"> <div class="row"> <div class="col-md-2"> </div> <div class="col-md-8"> <div class="searchBox"> <div class="leftTitle"> 答題統(tǒng)計 </div> <div> </div> </div> </div> <div class="col-md-2"> </div> </div> <div class="row"> <div class="col-md-2"> </div> <div class="col-md-4"> <div id="main"></div> </div> <div class="col-md-4"> <div id="main2"></div> </div> <div class="col-md-2"> </div> </div> </div> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/echarts.min.js"></script> <script> function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return unescape(r[2]); return null; } var user = JSON.parse(sessionStorage.getItem('user')); $.ajax({ url: "http://127.0.0.1:8081/common/total?userId=" + user.id, async: false, type: "POST", contentType: 'application/json', dataType: 'json', data: JSON.stringify({}), success: function(json) { initCharts1(json.data); var inputArray = json.data; // 定義對應(yīng)的題目類型名稱數(shù)組 var typeNameArray = ['單選題', '多選題', '判斷題']; // 結(jié)果數(shù)組 var resultArray = []; // 遍歷輸入數(shù)組 for (var i = 0; i < inputArray.length; i++) { // 構(gòu)造對象,并添加到結(jié)果數(shù)組中 var item = { value: inputArray[i], name: typeNameArray[i] }; resultArray.push(item); } initCharts(resultArray); } }); function initCharts(data1) { var chartDom = document.getElementById('main'); var myChart = echarts.init(chartDom); var option; option = { title: { text: '答題數(shù)統(tǒng)計', subtext: '', left: 'center' }, tooltip: { trigger: 'item' }, legend: { orient: 'vertical', left: 'left' }, series: [{ name: 'Access From', type: 'pie', radius: '50%', data: data1, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } }] }; myChart.setOption(option); }; function initCharts1(data2) { var chartDom = document.getElementById('main2'); var myChart = echarts.init(chartDom); var option; option = { xAxis: { type: 'category', data: ['單選題', '多選題', '判斷題'] }, yAxis: { type: 'value' }, series: [{ data: data2, type: 'bar', showBackground: true, backgroundStyle: { color: 'rgba(180, 180, 180, 0.2)' } }] }; myChart.setOption(option); }; </script> </body> </html>
總結(jié)
到此這篇關(guān)于基于Springboot+Vue實現(xiàn)的在線答題闖關(guān)系統(tǒng)的文章就介紹到這了,更多相關(guān)Springboot+Vue在線答題闖關(guān)系統(tǒng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用GSON庫轉(zhuǎn)換Java對象為JSON對象的進(jìn)階實例詳解
這篇文章主要介紹了使用GSON庫轉(zhuǎn)換Java對象為JSON對象的進(jìn)階實例詳解,包括注冊TypeAdapter及處理Enum類型等實際運用中可能遇到的一些復(fù)雜問題,需要的朋友可以參考下2016-06-06Spring Shell 命令行實現(xiàn)交互式Shell應(yīng)用開發(fā)
本文主要介紹了Spring Shell 命令行實現(xiàn)交互式Shell應(yīng)用開發(fā),能夠幫助開發(fā)者快速構(gòu)建功能豐富的命令行應(yīng)用程序,具有一定的參考價值,感興趣的可以了解一下2025-04-04Spring Cloud Gateway不同頻率限流的解決方案(每分鐘,每小時,每天)
SpringCloud Gateway 是 Spring Cloud 的一個全新項目,它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式。這篇文章主要介紹了Spring Cloud Gateway不同頻率限流(每分鐘,每小時,每天),需要的朋友可以參考下2020-10-10springboot自帶的緩存@EnableCaching用法
這篇文章主要介紹了springboot自帶的緩存@EnableCaching用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08MyBatis 動態(tài)SQL和緩存機(jī)制實例詳解
這篇文章主要介紹了MyBatis 動態(tài)SQL和緩存機(jī)制實例詳解,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-09-09Spring?Security自定義登錄頁面認(rèn)證過程常用配置
這篇文章主要為大家介紹了Spring?Security自定義登錄頁面認(rèn)證過程常用配置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08關(guān)于Controller層和Service層的類報錯問題及解決方案
這篇文章主要介紹了關(guān)于Controller層和Service層的類報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02Spring Boot集成Druid出現(xiàn)異常報錯的原因及解決
Druid 可以很好的監(jiān)控 DB 池連接和 SQL 的執(zhí)行情況,天生就是針對監(jiān)控而生的 DB 連接池。本文講述了Spring Boot集成Druid項目中discard long time none received connection異常的解決方法,出現(xiàn)此問題的同學(xué)可以參考下2021-05-05