Spring?Boot和Vue前后端分離項目架構(gòu)的全過程
Spring Boot+Vue 前后端分離項目架構(gòu)
項目流程:
1. SpringBoot 后端項目
1、新建一個 SpringBoot 工程,并添加項目開發(fā)過程中需要的相關(guān)依賴;
2、數(shù)據(jù)庫新建 book 數(shù)據(jù)表;
-- ---------------------------- -- Table structure for book -- ---------------------------- DROP TABLE IF EXISTS `book`; CREATE TABLE `book` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `title` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `publish` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `authors` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `createTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0), `updateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0), PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of book -- ---------------------------- INSERT INTO `book` VALUES (2, '數(shù)據(jù)結(jié)構(gòu)', '浙江出版社', '嚴威', '2022-03-18 14:38:22', '2022-03-18 14:38:25'); INSERT INTO `book` VALUES (5, '計算機組成原理', '機械工業(yè)出版社', '唐朔飛', '2022-03-14 14:38:28', '2022-03-15 14:38:36'); INSERT INTO `book` VALUES (6, '機器學(xué)習(xí)', '人民郵電出版社', '周志華', '2022-03-16 14:38:41', '2022-03-16 14:38:45'); INSERT INTO `book` VALUES (7, '圖論及其應(yīng)用', '科學(xué)技術(shù)出版社', '徐俊明', '2022-03-03 14:38:49', '2022-03-18 18:33:57'); INSERT INTO `book` VALUES (8, '推薦系統(tǒng)開發(fā)實戰(zhàn)', '電子工業(yè)出版社', '高團陽', '2022-03-14 14:38:57', '2022-03-16 14:39:02'); INSERT INTO `book` VALUES (9, '大數(shù)據(jù)導(dǎo)論', '機械工業(yè)出版社', '曾誠', '2022-03-10 14:39:06', '2022-03-12 14:39:09'); INSERT INTO `book` VALUES (13, 'Java從零基礎(chǔ)到實戰(zhàn)', '中國工信出版集團', '寧楠', '2022-03-18 17:05:18', '2022-03-18 17:05:18');
3、application.yml 配置數(shù)據(jù)源和項目啟動的端口號;
# 修改服務(wù)啟動的端口 server: port: 8181 spring: datasource: url: jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # 配置日志,打印執(zhí)行的sql語句 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
項目整體的目錄結(jié)構(gòu)如下:
4、創(chuàng)建實體類 Book.java;
@AllArgsConstructor @NoArgsConstructor @Data @TableName(value = "book") public class Book { @TableId(type = IdType.AUTO) private Long id; private String title; private String publish; private String authors; @TableField(value = "createTime", fill = FieldFill.INSERT) private Date createTime; @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
5、添加 MyBatis Plus 自動填充的處理器 config/DataHandler.java;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; @Component public class DataHandler implements MetaObjectHandler{ //插入時的填充策略 @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } //更新時的填充策略 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime", new Date(), metaObject); } }
6、持久化層 mapper/BookMapper.java;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.trainingl.entity.Book; import org.springframework.stereotype.Repository; @Repository //持久層注解 public interface BookMapper extends BaseMapper<Book> { //所有的CRUD操作都已經(jīng)編寫好了 }
7、服務(wù)層 service;
service/BookService.java
import com.trainingl.entity.Book; import java.util.List; //數(shù)據(jù)的增刪改查接口 public interface BookService { public List<Book> findAll(); public Book findById(Long id); public int insert(Book book); public int deleteById(Long id); public int updateById(Book book); }
service/Impl/BookServiceImpl.java
import com.trainingl.entity.Book; import com.trainingl.mapper.BookMapper; import com.trainingl.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class BookServiceImpl implements BookService { @Autowired private BookMapper bookMapper; @Override public List<Book> findAll() { //查詢搜索記錄 return bookMapper.selectList(null); } @Override public Book findById(Long id) { return bookMapper.selectById(id); } @Override public int insert(Book book) { return bookMapper.insert(book); } @Override public int deleteById(Long id) { return bookMapper.deleteById(id); } @Override public int updateById(Book book) { return bookMapper.updateById(book); } }
8、控制層 Controller;
controller/BookController.java
import com.trainingl.entity.Book; import com.trainingl.service.BookService; import org.apache.ibatis.annotations.Param; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController @CrossOrigin //跨域注解 public class BookController { @Autowired private BookService bookService; @RequestMapping("/booklist") public List<Book> booklist(){ return bookService.findAll(); } @RequestMapping("/addbook") public int addbook(@RequestBody Book book){ return bookService.insert(book); } @DeleteMapping("/deleteById/{id}") public int deleteById(@PathVariable("id") Long id){ Integer result = 0; result = bookService.deleteById(id); //刪除成功則返回受影響的行數(shù) return result; } @GetMapping("/findById/{id}") public Book findById(@PathVariable("id") Long id){ return bookService.findById(id); } @PutMapping("/updateById") public int updateById(@RequestBody Book book){ //返回修改的條數(shù) return bookService.updateById(book); } }
2. Vue 前端項目
1、主頁面 App.vue
<template> <div id="app"> <router-view/> </div> </template> <script> export default { name: 'App', components: { }, data(){ return{ } }, } </script>
2、數(shù)據(jù)列表視圖 views/table.vue
<template> <div> <el-table :data="tableData" border style="width: 70%"> <el-table-column fixed prop="id" label="編號" width="80"> </el-table-column> <el-table-column prop="title" label="書籍名稱" width="160"> </el-table-column> <el-table-column prop="publish" label="出版社" width="150"> </el-table-column> <el-table-column prop="authors" label="作者" width="120"> </el-table-column> <el-table-column prop="createTime" label="創(chuàng)建時間" width="150"> </el-table-column> <el-table-column prop="updateTime" label="修改時間" width="150"> </el-table-column> <el-table-column fixed="right" label="操作" width="150"> <template slot-scope="scope"> <el-button @click="del(scope.row)" type="danger" size="small">刪除</el-button> <el-button @click="edit(scope.row)" type="success" size="small">編輯</el-button> </template> </el-table-column> </el-table> <el-button type="primary" @click="addBook" icon="el-icon-edit" size="small">添加記錄</el-button> </div> </template> <script> export default { name: "table", methods: { addBook(){ this.$router.push("/addbook") }, del(row) { let _this = this; this.$confirm('此操作將永久刪除該記錄, 是否繼續(xù)?', '提示', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }).then(() => { this.$axios.delete("http://localhost:8181/deleteById/" + row.id).then(function (response) { if (response.data == 1) { //刷新頁面 location.reload(); } else { _this.$message({ showClose: true, message: '刪除信息失敗!', type: 'danger' }); } }) }) }, edit(row) { this.$router.push("/edit?id=" + row.id); } }, data() { return { tableData: [] } }, created(){ let _this = this; this.$axios.get("http://localhost:8181/booklist").then(function (response) { _this.tableData = response.data; }) } } </script> <style scoped> </style>
3、新增視圖文件 views/addBook.vue
<template> <div> <h2 style="padding-left: 200px">新增圖書信息</h2> <el-form :model="ruleForm" style="width: 500px;" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="書籍名稱" prop="title"> <el-input type="text" v-model="ruleForm.title" autocomplete="off"></el-input> </el-form-item> <el-form-item label="出版社" prop="publish"> <el-input type="text" v-model="ruleForm.publish" autocomplete="off"></el-input> </el-form-item> <el-form-item label="作者信息" prop="authors"> <el-input v-model.number="ruleForm.authors"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name: "addBook", data() { var checkAuthor = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入作者信息')); } else { callback(); } }; var validateTitle = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入書籍名稱')); } else { callback(); } }; var validatePublish = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入出版社')); } else { callback(); } }; return { ruleForm: { title: '', publish: '', authors: '' }, rules: { title: [ { validator: validateTitle, trigger: 'blur' } ], publish: [ { validator: validatePublish, trigger: 'blur' } ], authors: [ { validator: checkAuthor, trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { let _this = this; this.$refs[formName].validate((valid) => { if (valid) { this.$axios.post("http://localhost:8181/addbook", _this.ruleForm).then(function (response) { if(response.data == 1){ //跳轉(zhuǎn)到表格頁面 _this.$router.push('/table') } }) } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script> <style scoped> </style>
4、編輯或修改視圖文件 views/edit.vue
<template> <div> <h2 style="padding-left: 200px">修改圖書信息</h2> <el-form :model="ruleForm" style="width: 500px;" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="圖書編號"> <el-input type="text" readonly v-model="ruleForm.id" autocomplete="off"></el-input> </el-form-item> <el-form-item label="書籍名稱" prop="title"> <el-input type="text" v-model="ruleForm.title" autocomplete="off"></el-input> </el-form-item> <el-form-item label="出版社" prop="publish"> <el-input type="text" v-model="ruleForm.publish" autocomplete="off"></el-input> </el-form-item> <el-form-item label="作者信息" prop="authors"> <el-input v-model.number="ruleForm.authors"></el-input> </el-form-item> <el-form-item label="創(chuàng)建時間"> <el-input readonly v-model.number="ruleForm.createTime"></el-input> </el-form-item> <el-form-item label="修改時間"> <el-input readonly v-model.number="ruleForm.updateTime"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> </div> </template> <script> export default { name: "edit", data() { var checkAuthor = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入作者信息')); } else { callback(); } }; var validateTitle = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入書籍名稱')); } else { callback(); } }; var validatePublish = (rule, value, callback) => { if (value === '') { callback(new Error('請輸入出版社')); } else { callback(); } }; return { ruleForm: { id: '', title: '', publish: '', authors: '', createTime: '', updateTime: '' }, rules: { title: [ { validator: validateTitle, trigger: 'blur' } ], publish: [ { validator: validatePublish, trigger: 'blur' } ], authors: [ { validator: checkAuthor, trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { let _this = this; this.$refs[formName].validate((valid) => { if (valid) { this.$axios.put("http://localhost:8181/updateById", _this.ruleForm).then(function (response) { if(response.data === 1){ //跳轉(zhuǎn)到表格頁面 _this.$router.push('/table') } }) } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } }, mounted(){ let _this = this; this.$axios.get("http://localhost:8181/findById/" + this.$route.query.id).then(function (response) { _this.ruleForm = response.data; }); } } </script> <style scoped> </style>
5、路由文件 router.js
import Vue from 'vue' //1.導(dǎo)入路由依賴,安裝 vue-router組件后系統(tǒng)帶有的依賴 import VueRouter from 'vue-router' //2.導(dǎo)入兩個頁面 import Login from "@/views/login"; import Second from "@/views/Second"; import Table from "@/views/table"; import AddBook from "@/views/addBook"; import Edit from "@/views/edit"; // 3.使用路由 Vue.use(VueRouter); //4.創(chuàng)建路由對象,new VueRouter為上面import設(shè)置的名稱 const router = new VueRouter({ //沒有history,訪問URL會有# mode: "history", routes: [ { path:"/login", component: Login }, { path:"/second", component: Second }, { path:"/table", component: Table }, { path:"/addbook", component: AddBook }, { path:"/edit", component: Edit }, ] }); export default router;
6、組件的全局配置 main.js
import Vue from 'vue' import App from './App.vue' import router from "./router/index" import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import axios from "axios" import qstring from "querystring" // Vue 全局Vue對象,prototype原型設(shè)置全局屬性 Vue.prototype.$axios = axios Vue.prototype.$qstring=qstring Vue.config.productionTip = false; Vue.use(ElementUI); new Vue({ router, render: h => h(App), }).$mount('#app')
總結(jié)
到此這篇關(guān)于Spring Boot和Vue前后端分離項目架構(gòu)的文章就介紹到這了,更多相關(guān)Spring Boot Vue前后端分離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot過濾器FilterRegistrationBean實現(xiàn)方式
這篇文章主要介紹了spring boot過濾器FilterRegistrationBean實現(xiàn)方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10Spring MVC攔截器_動力節(jié)點Java學(xué)院整理
Spring MVC的攔截器,是屬于HandlerMapping級別的,可以有多個HandlerMapping ,每個HandlerMapping可以有自己的攔截器,具體內(nèi)容詳情大家通過本文學(xué)習(xí)吧2017-08-08Java方法參數(shù)是引用調(diào)用還是值調(diào)用?
Java方法參數(shù)是引用調(diào)用還是值調(diào)用?這是一個值得思考的問題。閱讀本文,找出答案2016-02-02Java concurrency之AtomicLong原子類_動力節(jié)點Java學(xué)院整理
AtomicLong是作用是對長整形進行原子操作。下面通過本文給大家介紹Java concurrency之AtomicLong原子類的相關(guān)知識,感興趣的朋友一起看看吧2017-06-06