SpringBoot SSMP 整合案例分享
前言:
- - 先開(kāi)發(fā)基礎(chǔ)CRUD功能,做一層測(cè)一層
- - 調(diào)通頁(yè)面,確認(rèn)異步提交成功后,制作所有功能
- - 添加分頁(yè)功能與查詢(xún)功能
1 搭建SpringBoot應(yīng)用
- 勾選 SpringMVC 與 MySQL 坐標(biāo)
- 修改配置文件為yml格式
- 設(shè)置端口為80方便訪問(wèn)(可選)
2 實(shí)體類(lèi)開(kāi)發(fā)
Lombok,一個(gè)Java類(lèi)庫(kù),提供了一組注解,簡(jiǎn)化POJO實(shí)體類(lèi)開(kāi)發(fā)
- lombok版本由SpringBoot提供,無(wú)需指定版本。
- 常用注解:@Data
- 為當(dāng)前實(shí)體類(lèi)在編譯期設(shè)置對(duì)應(yīng)的 get/set 方法,toString方法,hashCode方法,equals方法等
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}3 數(shù)據(jù)層(dao層)開(kāi)發(fā)
技術(shù)實(shí)現(xiàn)方案:
- MyBatisPlus
- Druid
- (1)導(dǎo)入 MyBatisPlus 與 Druid 對(duì)應(yīng)的 starter
- (2)配置數(shù)據(jù)源與 MyBatisPlus 對(duì)應(yīng)的基礎(chǔ)配置(id 生成策略使用數(shù)據(jù)庫(kù)自增策略)
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_db?servierTimezone=UTC
username: root
password: root
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto(3)繼承 BaseMapper 并指定泛型
@Mapper
public interface BookDao extends BaseMapper<Book> {
}(4)制作測(cè)試類(lèi)測(cè)試結(jié)果
@SpringBootTest
public class BookDaoTestCase {
@Autowired
private BookDao bookDao;
@Test
void testSave(){
Book book = new Book();
book.setName("測(cè)試數(shù)據(jù)");
book.setType("測(cè)試類(lèi)型");
bookDao.insert(book);
}
@Test
void testGetById() {
System.out.println(bookDao.selectById(1));
}
}(5)為方便調(diào)試可以開(kāi)啟 MyBatisPlus 的日志(使用配置方式開(kāi)啟日志,設(shè)置日志輸出方式為標(biāo)準(zhǔn)輸出)
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
id-type: auto
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4 數(shù)據(jù)層開(kāi)發(fā)分頁(yè)功能
- 分頁(yè)操作需要設(shè)定分頁(yè)對(duì)象
IPage,IPage 對(duì)象中封裝了分頁(yè)操作中的所有數(shù)據(jù)(數(shù)據(jù)、當(dāng)前頁(yè)碼值、每頁(yè)數(shù)據(jù)總量、最大頁(yè)碼值、數(shù)據(jù)總量)。 - 分頁(yè)操作是在 MyBatisPlus 的常規(guī)操作基礎(chǔ)上增強(qiáng)得到,內(nèi)部是動(dòng)態(tài)的拼寫(xiě) SQL 語(yǔ)句,使用 MyBatisPlus 攔截器實(shí)現(xiàn)。
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// MyBatisPlus攔截器
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//1.定義Mp攔截
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//2.添加具體的攔截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
5 數(shù)據(jù)層開(kāi)發(fā)?條件查詢(xún)功能 QueryWrapper
- 使用
QueryWrapper對(duì)象封裝查詢(xún)條件,推薦使用LambdaQueryWrapper對(duì)象,將所有查詢(xún)操作封裝成方法調(diào)用。
// 條件查詢(xún)功能
@Test
void testGetByCondition(){
IPage page = new Page(1,10);
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
lqw.like(Book::getName,"Spring");
bookDao.selectPage(page,lqw);
}
@Test
void testGetByCondition2(){
QueryWrapper<Book> qw = new QueryWrapper<Book>();
qw.like("name","Spring");
bookDao.selectList(qw);
}
- 支持動(dòng)態(tài)拼寫(xiě)查詢(xún)條件
Strings.isNotEmpty(name)
@Test
void testGetByCondition(){
String name = "Spring";
IPage page = new Page(1,10);
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
lqw.like(Strings.isNotEmpty(name),Book::getName,"Spring");
bookDao.selectPage(page,lqw);
}6 業(yè)務(wù)層(Service層)開(kāi)發(fā)
# Service層接口定義與數(shù)據(jù)層接口定義具有較大區(qū)別,不要混用 // 業(yè)務(wù)層關(guān)注的是業(yè)務(wù)操作 login(String username,String password); // 數(shù)據(jù)層關(guān)注的是數(shù)據(jù)庫(kù)操作 selectByUserNameAndPassword(String username,String password);
// 接口定義
public interface BookService {
boolean save(Book book);
boolean delete(Integer id);
boolean update(Book book);
Book getById(Integer id);
List<Book> getAll();
IPage<Book> getByPage(int currentPage,int pageSize);
}// 實(shí)現(xiàn)類(lèi)定義
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
public Boolean save(Book book) {
return bookDao.insert(book) > 0;
}
public Boolean delete(Integer id) {
return bookDao.deleteById(id) > 0;
}
public Boolean update(Book book) {
return bookDao.updateById(book) > 0;
}
public Book getById(Integer id) {
return bookDao.selectById(id);
}
public List<Book> getAll() {
return bookDao.selectList(null);
}
public IPage<Book> getByPage(int currentPage, int pageSize) {
IPage page = new Page<Book>(currentPage,pageSize);
return bookDao.selectPage(page,null);
}
}7 業(yè)務(wù)層開(kāi)發(fā)——快速開(kāi)發(fā)?使用ISerivce和ServiceImpl
- > - 快速開(kāi)發(fā)方案
- > - 使用MyBatisPlus提供的業(yè)務(wù)層通用接口(ISerivce<T>)與業(yè)務(wù)層通用實(shí)現(xiàn)類(lèi)(`ServiceImpl<M,T>`)
- > - 在通用類(lèi)基礎(chǔ)上做功能重載或功能追加
- > - 注意重載時(shí)不要覆蓋原始操作,避免原始提供的功能丟失
接口:
public interface BookService extends IService<Book> {
// 追加的操作與原始操作通過(guò)名稱(chēng)區(qū)分,功能類(lèi)似
boolean saveBook(Book book);
boolean modify(Book book);
boolean delete(Integer id);
IPage<Book> getPage(int currentPage, int pageSize);
IPage<Book> getPage(int currentPage, int pageSize, Book book);
}實(shí)現(xiàn)類(lèi):
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements BookService {
@Autowired
private BookDao bookDao;
@Override
public boolean saveBook(Book book) {
return bookDao.insert(book) > 0;
}
@Override
public boolean modify(Book book) {
return bookDao.updateById(book) > 0;
}
@Override
public boolean delete(Integer id) {
return bookDao.deleteById(id) > 0;
}
@Override
public IPage<Book> getPage(int currentPage, int pageSize) {
IPage page = new Page(currentPage, pageSize);
bookDao.selectPage(page, null);
return page;
}
@Override
public IPage<Book> getPage(int currentPage, int pageSize, Book book) {
LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<Book>();
lqw.like(Strings.isNotEmpty(book.getType()), Book::getType, book.getType());
lqw.like(Strings.isNotEmpty(book.getName()), Book::getName, book.getName());
lqw.like(Strings.isNotEmpty(book.getDescription()), Book::getDescription, book.getDescription());
IPage page = new Page(currentPage, pageSize);
bookDao.selectPage(page, lqw);
return page;
}
}8 基于 Restful 進(jìn)行表現(xiàn)層開(kāi)發(fā)
- 基于Restful制作表現(xiàn)層接口
- 新增:POST
- 刪除:DELETE
- 修改:PUT
- 查詢(xún):GET
- 接收參數(shù)
- 實(shí)體數(shù)據(jù):
@RequestBody - 路徑變量:
@PathVariable
- 實(shí)體數(shù)據(jù):
// 功能測(cè)試
@GetMapping("/{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage, @PathVariable int pageSize, Book book) {
IPage<Book> page = bookService.getPage(currentPage, pageSize, book);
// 如果當(dāng)前頁(yè)碼大于了總頁(yè)碼,那么將最大頁(yè)碼值作為當(dāng)前頁(yè)碼,重新執(zhí)行查詢(xún)操作
// 源碼中 long pages = this.getTotal() / this.getSize();
if (currentPage > page.getPages()) {
page = bookService.getPage((int) page.getPages(), pageSize, book);
}
return new R(true, page);
} 
9 表現(xiàn)層消息一致性處理 R(統(tǒng)一返回值)

設(shè)計(jì)表現(xiàn)層返回結(jié)果的模型類(lèi),用于后端與前端進(jìn)行數(shù)據(jù)格式統(tǒng)一,也稱(chēng)為前后端數(shù)據(jù)協(xié)議:
- 1. 設(shè)計(jì)統(tǒng)一的返回值結(jié)果類(lèi)型便于前端開(kāi)發(fā)讀取數(shù)據(jù)
- 2. 返回值結(jié)果類(lèi)型可以根據(jù)需求自行設(shè)定,沒(méi)有固定格式
- 3. 返回值結(jié)果模型類(lèi)用于后端與前端進(jìn)行數(shù)據(jù)格式統(tǒng)一,也稱(chēng)為前后端數(shù)據(jù)協(xié)議
- - flag:false
- - Data: null
- - 消息(msg): 要顯示信息

10 前后端協(xié)議聯(lián)調(diào)
- 前后端分離結(jié)構(gòu)設(shè)計(jì)中頁(yè)面歸屬前端服務(wù)器
- 單體工程中頁(yè)面放置在 resources / static 目錄下(建議執(zhí)行clean)
- 前端發(fā)送異步請(qǐng)求,調(diào)用后端接口
- created鉤子函數(shù)用于初始化頁(yè)面時(shí)發(fā)起調(diào)用
- 頁(yè)面使用 axios 發(fā)送異步請(qǐng)求獲取數(shù)據(jù)后確認(rèn)前后端是否聯(lián)通
//列表
getAll() {
axios.get("/books").then((res)=>{
console.log(res.data);
});
},查詢(xún)
將查詢(xún)數(shù)據(jù)返回到頁(yè)面,利用前端數(shù)據(jù)雙向綁定進(jìn)行數(shù)據(jù)展示:
//列表
getAll() {
axios.get("/books").then((res)=>{
this.dataList = res.data.data;
});
},添加
- 1. 請(qǐng)求方式使用POST調(diào)用后臺(tái)對(duì)應(yīng)操作
- 2. 添加操作結(jié)束后動(dòng)態(tài)刷新頁(yè)面加載數(shù)據(jù)
- 3. 根據(jù)操作結(jié)果不同,顯示對(duì)應(yīng)的提示信息
- 4. 彈出添加Div時(shí)清除表單數(shù)據(jù)
//彈出添加窗口
handleCreate() {
this.dialogFormVisible = true;
},
//清除數(shù)據(jù),重置表單
resetForm() {
this.formData = {};
},
//彈出添加窗口
handleCreate() {
this.dialogFormVisible = true;
this.resetForm();
},
//添加
handleAdd () {
//發(fā)送異步請(qǐng)求
axios.post("/books",this.formData).then((res)=>{
//如果操作成功,關(guān)閉彈層,顯示數(shù)據(jù)
if(res.data.flag){
this.dialogFormVisible = false;
this.$message.success("添加成功");
}else {
this.$message.error("添加失敗");
}
}).finally(()=>{
this.getAll();
});
},
//取消添加
cancel(){
this.dialogFormVisible = false;
this.$message.info("操作取消");
}, 刪除
- 1. 請(qǐng)求方式使用Delete調(diào)用后臺(tái)對(duì)應(yīng)操作
- 2. 刪除操作需要傳遞當(dāng)前行數(shù)據(jù)對(duì)應(yīng)的id值到后臺(tái)
- 3. 刪除操作結(jié)束后動(dòng)態(tài)刷新頁(yè)面加載數(shù)據(jù)
- 4. 根據(jù)操作結(jié)果不同,顯示對(duì)應(yīng)的提示信息
- 5. 刪除操作前彈出提示框避免誤操作
// 刪除
handleDelete(row) {
axios.delete("/books/"+row.id).then((res)=>{
if(res.data.flag){
this.$message.success("刪除成功");
}else{
this.$message.error("刪除失敗");
}
}).finally(()=>{
this.getAll();
});
}
// 刪除
handleDelete(row) {
//1.彈出提示框
this.$confirm("此操作永久刪除當(dāng)前數(shù)據(jù),是否繼續(xù)?","提示",{
type:'info'
}).then(()=>{
//2.做刪除業(yè)務(wù)
axios.delete("/books/"+row.id).then((res)=>{
……
}).finally(()=>{
this.getAll();
});
}).catch(()=>{
//3.取消刪除
this.$message.info("取消刪除操作");
});
}//彈出編輯窗口
handleUpdate(row) {
axios.get("/books/"+row.id).then((res)=>{
if(res.data.flag){
//展示彈層,加載數(shù)據(jù)
this.formData = res.data.data;
this.dialogFormVisible4Edit = true;
}else{
this.$message.error("數(shù)據(jù)同步失敗,自動(dòng)刷新"); }
});
},
//刪除
handleDelete(row) {
axios.delete("/books/"+row.id).then((res)=>{
if(res.data.flag){
this.$message.success("刪除成功");
}else{
this.$message.error("數(shù)據(jù)同步失敗,自動(dòng)刷新");
}
}).finally(()=>{
this.getAll();
});
}1.加載要修改數(shù)據(jù)通過(guò)傳遞當(dāng)前行數(shù)據(jù)對(duì)應(yīng)的id值到后臺(tái)查詢(xún)數(shù)據(jù) 2.利用前端數(shù)據(jù)雙向綁定將查詢(xún)到的數(shù)據(jù)進(jìn)行回顯
修改
- 1. 請(qǐng)求方式使用PUT調(diào)用后臺(tái)對(duì)應(yīng)操作
- 2. 修改操作結(jié)束后動(dòng)態(tài)刷新頁(yè)面加載數(shù)據(jù)(同新增)
- 3. 根據(jù)操作結(jié)果不同,顯示對(duì)應(yīng)的提示信息(同新增)
//修改
handleEdit() {
axios.put("/books",this.formData).then((res)=>{
//如果操作成功,關(guān)閉彈層并刷新頁(yè)面
if(res.data.flag){
this.dialogFormVisible4Edit = false;
this.$message.success("修改成功");
}else {
this.$message.error("修改失敗,請(qǐng)重試");
}
}).finally(()=>{
this.getAll();
});
},
// 取消添加和修改
cancel(){
this.dialogFormVisible = false;
this.dialogFormVisible4Edit = false;
this.$message.info("操作取消");
},11 業(yè)務(wù)消息一致性處理

對(duì)異常進(jìn)行統(tǒng)一處理,出現(xiàn)異常后,返回指定信息:
- 使用注解
@RestControllerAdvice定義 SpringMVC 異常處理器用來(lái)處理異常的 - 異常處理器必須被掃描加載,否則無(wú)法生效
- 表現(xiàn)層返回結(jié)果的模型類(lèi)中添加消息屬性用來(lái)傳遞消息到頁(yè)面
// 作為springmvc的異常處理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
// 攔截所有的異常信息
@ExceptionHandler(Exception.class)
public R doException(Exception e){
// 記錄日志
// 通知運(yùn)維
// 通知開(kāi)發(fā)
e.printStackTrace();
return new R("服務(wù)器故障,請(qǐng)稍后重試哈!");
}
}12 分頁(yè)功能
頁(yè)面使用 el 分頁(yè)組件添加分頁(yè)功能:
- 定義分頁(yè)組件需要使用的數(shù)據(jù)并將數(shù)據(jù)綁定到分頁(yè)組件
- 替換查詢(xún)?nèi)抗δ転榉猪?yè)功能
- 加載分頁(yè)數(shù)據(jù)
- 分頁(yè)頁(yè)碼值切換
使用el分頁(yè)組件:
- 定義分頁(yè)組件綁定的數(shù)據(jù)模型
- 異步調(diào)用獲取分頁(yè)數(shù)據(jù)
- 分頁(yè)數(shù)據(jù)頁(yè)面回顯
到此這篇關(guān)于SpringBoot SSMP 整合案例分享的文章就介紹到這了,更多相關(guān)SpringBoot SSMP 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中char[] 和 String 類(lèi)型占用字節(jié)大小問(wèn)題
這篇文章主要介紹了Java中char[] 和 String 類(lèi)型占用字節(jié)大小問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Intellij IDEA Debug調(diào)試技巧(小結(jié))
這篇文章主要介紹了Intellij IDEA Debug調(diào)試技巧(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(55)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-08-08
Spark MLlib隨機(jī)梯度下降法概述與實(shí)例
這篇文章主要為大家詳細(xì)介紹了Spark MLlib隨機(jī)梯度下降法概述與實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Java數(shù)組隊(duì)列概念與用法實(shí)例分析
這篇文章主要介紹了Java數(shù)組隊(duì)列概念與用法,結(jié)合實(shí)例形式分析了Java數(shù)組隊(duì)列相關(guān)概念、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
SpringBoot如何通過(guò)配置文件(yml,properties)限制文件上傳大小
這篇文章主要介紹了SpringBoot如何通過(guò)配置文件(yml,properties)限制文件上傳大小,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
IDEA中創(chuàng)建maven項(xiàng)目引入相關(guān)依賴(lài)無(wú)法下載jar問(wèn)題及解決方案
這篇文章主要介紹了IDEA中創(chuàng)建maven項(xiàng)目引入相關(guān)依賴(lài)無(wú)法下載jar問(wèn)題及解決方案,本文通過(guò)圖文并茂的形式給大家分享解決方案,需要的朋友可以參考下2020-07-07

