vue和java实现页面增删改_SpringBoot-Vue实现增删改查及分页小DEMO

本文介绍了如何使用Spring Boot后端技术和Vue前端技术来开发一个简单的增删改查及分页功能的DEMO。涉及到的技术栈包括Spring Boot、Mybatis、Vue、Axios等,详细讲解了从环境搭建到前后端交互的全过程。通过此教程,读者可以了解SpringBoot结合Vue完成前后端分离项目的开发流程。
摘要由CSDN通过智能技术生成

前言

主要通过后端 Spring Boot 技术和前端 Vue 技术来简单开发一个demo,实现增删改查、分页功能以及了解Springboot搭配vue完成前后端分离项目的开发流程。

开发栈

前端

开发工具:WebStorm

开发框架:vue + axios

包管理工具: npm

打包工具:webpack

后端

开发工具:IDEA

开发框架:Springboot + mybatis

打包工具:maven

数据库: MySQL

PS:假设以上的的工具你都安装好啦,写CRUD小DEMO时进坑了,这篇blog参考一下,仅供参考,仅供参考😤,,如有不足请不吝赐教。

后端开发环境搭建

1、File->New->Project...

075746f65b40c6b35522a4858c2fd1c1.png

2、选择 Spring Initializr ,然后选择默认的 url 点击next

c75a2879bd269aa1ca8a0c2d80deab97.png

3、勾选Spring Web、SQL模板,next

a73ef793a20e2a53c2c5ad607b6b5829.png

4、点击finish,搭建完成

2e2fef12dcb3d2ae482196fed8036540.png

后端开发过程

1、更新pom.xml如下:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.example

demo

0.0.1-SNAPSHOT

springboot-mybatis

org.springframework.boot

spring-boot-starter-parent

2.1.3.RELEASE

1.2.0

5.1.39

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.mybatis.spring.boot

mybatis-spring-boot-starter

${mybatis-spring-boot}

mysql

mysql-connector-java

${mysql-connector}

junit

junit

4.12

2、新建 demo\src\main\java\com\example\demo\entity\User.java

package com.example.demo.entity;

public class User {

private int userId;

private String userDate;

private String userName;

private String userAddress;

//省略get() and set()

}

3、更新demo\src\main\resources\application.properties

## 数据源配置

spring.datasource.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8

spring.datasource.username=root

spring.datasource.password=123

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

## Mybatis 配置

mybatis.typeAliasesPackage=org.spring.springboot.domain

mybatis.mapperLocations=classpath:mapper/*.xml

## 端口

server.port=8081

4、新建demo\src\main\java\com\example\demo\mapper\UserMapper.java

package com.example.demo.mapper;

import com.example.demo.entity.User;

import org.apache.ibatis.annotations.Mapper;

import java.util.List;

Mapper

public interface UserMapper {

public List findUserByName(String userName);

public List ListUser();

public List queryPage(Integer startRows);

public int getRowCount();

public int insertUser(User user);

public int delete(int userId);

public int Update(User user);

}

5、新建demo\src\main\resources\mapper\UserMapper.xml

/p>

"-//mybatis.org//DTD com.example.Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT * FROM user

SELECT * FROM user

where userName like concat(concat('%',#{userName}),'%')

order by userId desc

select * from user

order by userId desc

limit #{startRows},5

select count(*) from user

INSERT INTO user

(

userId,userDate,userName,userAddress

)

VALUES (

#{userId},

#{userDate, jdbcType=VARCHAR},

#{userName, jdbcType=VARCHAR},

#{userAddress, jdbcType=VARCHAR}

)

delete from user where userId=#{userId}

update user

set user.userDate=#{userDate},user.userName=#{userName},user.userAddress=#{userAddress}

where user.userId=#{userId}

6、新建demo\src\main\java\com\example\demo\service\UserService.java

package com.example.demo.service;

import com.example.demo.entity.User;

import com.example.demo.mapper.UserMapper;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

Service

public class UserService {

@Autowired

private UserMapper userMapper;

public List findByName(String userName) {

return userMapper.findUserByName(userName);

}

public List queryPage(Integer startRows) {

return userMapper.queryPage(startRows);

}

public int getRowCount() {

return userMapper.getRowCount();

}

public User insertUser(User user) {

userMapper.insertUser(user);

return user;

}

public List ListUser(){

return userMapper.ListUser();

}

public int Update(User user){

return userMapper.Update(user);

}

public int delete(int userId){

return userMapper.delete(userId);

}

}

7、新建demo\src\main\java\com\example\demo\controller\UserCtrl.java

package com.example.demo.controller;

import com.example.demo.entity.User;

import com.example.demo.service.UserService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;

import java.util.List;

RestController

public class UserCtrl {

@Autowired

private UserService userService;

@RequestMapping(value = "/delete", method = RequestMethod.POST)

public Integer delete(Integer userId) {

System.out.println(userId);

int result = userService.delete(userId);

return result;

}

@RequestMapping(value = "/update", method = RequestMethod.POST)

@ResponseBody

public String update(User user) {

int result = userService.Update(user);

if (result >= 1) {

return "修改成功";

} else {

return "修改失败";

}

}

@RequestMapping(value = "/insert", method = RequestMethod.POST)

public User insert(User user) {

return userService.insertUser(user);

}

@RequestMapping("/ListUser")

@ResponseBody

public List ListUser() {

return userService.ListUser();

}

@RequestMapping("/ListByName")

@ResponseBody

public List ListUserByName(String userName) {

return userService.findByName(userName);

}

/**

* 分页

* @return

*/

@RequestMapping(value="/page")

@ResponseBody

public List page(Integer page){

int pageNow = page == null ? 1 : page;

int pageSize = 5;

int startRows = pageSize*(pageNow-1);

List list = userService.queryPage(startRows);

return list;

}

/**

* rows

* @return

*/

@RequestMapping(value="/rows")

@ResponseBody

public int rows(){

return userService.getRowCount();

}

}

8、启动MySQL数据库,新建或执行如下表:

55bc20ba371bcc8ffca5d3d33b083be7.png

SET NAMES utf8mb4;

SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------

-- Table structure for user

-- ----------------------------

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`userId` int(20) NOT NULL AUTO_INCREMENT,

`userDate` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

`userName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

`userAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

PRIMARY KEY (`userId`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 71 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------

-- Records of user

-- ----------------------------

INSERT INTO `user` VALUES (15, '2019-09-29T03:17:12.000Z', '王老三', '上海市普陀区金沙江路 1515 弄');

INSERT INTO `user` VALUES (16, '2019-09-29T03:27:05.000Z', '张小四', '上海市普陀区金沙江路 1514 弄');

INSERT INTO `user` VALUES (17, '2019-09-29T03:30:04.000Z', '王老五', '上海市普陀区金沙江路 1513弄');

INSERT INTO `user` VALUES (18, '2019-09-29T03:33:15.000Z', '小六子', '上海市普陀区金沙江路 1512弄');

INSERT INTO `user` VALUES (20, '2019-09-29T03:33:15.000Z', '王老八', '上海市普陀区金沙江路 1512弄');

INSERT INTO `user` VALUES (21, '2019-09-29T05:42:52.000Z', '王大拿', '上海市普陀区金沙江路 1511弄');

INSERT INTO `user` VALUES (22, '2019-09-29T05:43:50.000Z', '小九九', '上海市普陀区金沙江路 1510弄');

INSERT INTO `user` VALUES (23, '2019-09-29T05:43:50.000Z', '刘诗诗', '上海市普陀区金沙江路 1499弄');

INSERT INTO `user` VALUES (24, '2019-09-29T05:46:07.000Z', '扎昂四四', '上海市大湾区科技路');

INSERT INTO `user` VALUES (25, '2019-09-29T05:46:07.000Z', '扎昂四四新东方', '上海市大湾区科技路2001号');

INSERT INTO `user` VALUES (26, '2019-09-29T05:46:07.000Z', '王小虎', '上海市大湾区科技路2002号');

INSERT INTO `user` VALUES (27, '2019-09-29T05:46:07.000Z', '抽拉吧唧', '上海市大湾区科技路2003号');

INSERT INTO `user` VALUES (28, '2019-09-29T05:46:07.000Z', '年啦编辑', '上海市大湾区科技路2004号');

INSERT INTO `user` VALUES (29, '2019-09-29T05:46:07.000Z', '你多少', '上海市普陀区金沙江路 1211弄');

INSERT INTO `user` VALUES (30, '2019-09-29T05:46:07.000Z', '反发达', '上海市普陀区金沙江路 1212弄');

INSERT INTO `user` VALUES (31, '2019-09-29T05:51:20.000Z', '发官方', '上海市普陀区金沙江路 1213弄');

INSERT INTO `user` VALUES (32, '2019-09-29T05:51:20.000Z', '方还有', '上海市普陀区金沙江路 1214弄');

INSERT INTO `user` VALUES (33, '2019-09-29T05:51:20.000Z', '过不分', '上海市普陀区金沙江路 1498弄');

INSERT INTO `user` VALUES (34, '2019-09-29T05:51:20.000Z', '菜市场', '上海市普陀区金沙江路 1497弄');

INSERT INTO `user` VALUES (35, '2019-09-29T05:51:20.000Z', '权威的', '上海市普陀区金沙江路 1496弄');

INSERT INTO `user` VALUES (36, '2019-09-29T05:55:09.000Z', '冈反对的', '上海市大湾区科技路2001号');

INSERT INTO `user` VALUES (37, '2019-09-29T05:55:09.000Z', '冈反对', '上海市大湾区科技路2003号');

INSERT INTO `user` VALUES (38, '2019-09-29T05:55:09.000Z', '偶哦里面', '上海市大湾区科技路2004号');

INSERT INTO `user` VALUES (39, '2019-09-29T05:55:09.000Z', '偶哦韩大苏打', '上海市大湾区科技路2005号');

INSERT INTO `user` VALUES (40, '2019-09-29T05:55:09.000Z', '偶哦匀', '上海市大湾区科技路2006号');

INSERT INTO `user` VALUES (41, '2019-09-29T05:55:09.000Z', '敢哦匀', '上海市大湾区科技路2006号');

INSERT INTO `user` VALUES (42, '2019-09-29T05:55:09.000Z', '敢孩', '上海市大湾区科技路2006号');

INSERT INTO `user` VALUES (43, '2019-09-29T05:55:09.000Z', '敢女孩', '上海市大湾区科技路2007号');

INSERT INTO `user` VALUES (45, '2019-09-29T05:55:09.000Z', '工行行', '上海市大湾区科技路2008号');

INSERT INTO `user` VALUES (46, '2019-09-29T05:55:09.000Z', '家好吗', '上海市大湾区科技路2008号');

INSERT INTO `user` VALUES (47, '2019-09-29T05:55:09.000Z', '的程度', '上海市大湾区科技路2009号');

INSERT INTO `user` VALUES (48, '2019-09-29T05:55:09.000Z', '称得上', '上海市大湾区科技路2009号');

INSERT INTO `user` VALUES (49, '2019-09-29T05:55:09.000Z', '韩国和', '上海市大湾区科技路2010号');

INSERT INTO `user` VALUES (50, '2019-09-29T05:55:09.000Z', '韩好', '上海市大湾区科技路2010号');

INSERT INTO `user` VALUES (51, '2019-09-29T05:55:09.000Z', '韩吧', '上海市大湾区科技路2011号');

INSERT INTO `user` VALUES (52, '2019-09-29T05:55:09.000Z', '韩吧吧', '上海市大湾区科技路2012号');

INSERT INTO `user` VALUES (53, '2019-09-29T05:55:09.000Z', '长度是', '上海市大湾区科技路2013号');

INSERT INTO `user` VALUES (54, '2019-09-29T05:55:09.000Z', '比如合', '上海市大湾区科技路2014号');

INSERT INTO `user` VALUES (55, '2019-09-29T05:55:09.000Z', '如合境', '上海市大湾区科技路2015号');

INSERT INTO `user` VALUES (56, '2019-09-29T05:55:09.000Z', '如合国', '上海市大湾区科技路2016号');

INSERT INTO `user` VALUES (57, '2019-09-29T05:55:09.000Z', '如更好', '上海市大湾区科技路2017号');

INSERT INTO `user` VALUES (58, '2019-09-29T05:55:09.000Z', '如更法', '上海市大湾区科技路2018号');

INSERT INTO `user` VALUES (59, '2019-09-29T05:55:09.000Z', '反对', '上海市大湾区科技路2019号');

INSERT INTO `user` VALUES (60, '2019-09-29T05:55:09.000Z', '如国部', '上海市大湾区科技路2019号');

INSERT INTO `user` VALUES (61, '2019-09-29T06:04:15.000Z', '奇热网', '上海市普陀区金沙江路 1496弄');

INSERT INTO `user` VALUES (62, '2019-09-29T06:04:33.000Z', '反对法', '上海市普陀区金沙江路 1495弄');

INSERT INTO `user` VALUES (63, '2019-09-29T06:04:33.000Z', '的风格', '上海市普陀区金沙江路 1494弄');

INSERT INTO `user` VALUES (64, '2019-09-29T06:04:33.000Z', '广泛同', '上海市大湾区科技路2020号');

INSERT INTO `user` VALUES (65, '2019-09-10T06:04:33.000Z', '但仍然', '上海市普陀区金沙江路 1493弄');

INSERT INTO `user` VALUES (66, '2019-09-29T06:10:28.000Z', 'vdfv', '放到电饭锅的');

INSERT INTO `user` VALUES (67, '2019-09-14T16:00:00.000Z', '朱老六', '上海市高新区上海中心');

INSERT INTO `user` VALUES (69, '2019-09-10T16:00:00.000Z', '是的', ' 学生的三十四分');

INSERT INTO `user` VALUES (70, '2019-09-29T07:51:44.000Z', '张小子', '上海市浦东区1234号');

SET FOREIGN_KEY_CHECKS = 1;

9、后端就写完了,整体结构如下:

68d2e64eb94c9a0cb724e80abb8e50e6.png

10、run 'DemoApplication'启动项目,控制台没报错就用浏览器测试一下,在浏览器中输入http://localhost:8081/page?page=3 如果能出现如下字符串就👌,已安装postman的可以每个方法都试一下:

5ee769ab1d1aad0f02a555a04bf9f631.png

前端开发环境搭建

1、win+R->cmd->进入项目目录依次执行命令:vue init webpack projectName、cd projectName、npm install、npm run dev如图所示:

e101a697f440ac893539811e859820da.png

2、打开浏览器输入:http://localhost:8080,效果如图:

45078d748ba31f91fdc6827c47298ab4.png

3、用WebStorm打开项目:File->Open...->vue01(projectName)

86368e73cf98ef5037e6206aaabca9eb.png

4、Vue-cli项目结构如图:

e08bf080559473d9fb4c9acda53d2987.png

前端开发过程

1、在项目根目录安装axios执行命令npm install axios,安装element ui 执行命令npm i element-ui -S

2、更新vue01\src\App.vue

export default {

name: 'App',

data() {

return {

}

},

methods: {

}

}

#app {

font-family: 'Avenir', Helvetica, Arial, sans-serif;

-webkit-font-smoothing: antialiased;

-moz-osx-font-smoothing: grayscale;

margin: 0px;

padding: 0px;

}

3、更新vue01\src\main.js

// The Vue build version to load with the `import` command

// (runtime-only or standalone) has been set in webpack.base.conf with an alias.

import Vue from 'vue'

import App from './App'

import router from './router'

import elementUI from 'element-ui'

import 'element-ui/lib/theme-chalk/index.css'

import 'element-ui/lib/theme-chalk/display.css'

Vue.use(elementUI)

import axios from 'axios'

Vue.prototype.axios = axios

import qs from 'qs';

Vue.prototype.qs = qs;

Vue.config.productionTip = false

/* eslint-disable no-new */

new Vue({

el: '#app',

router,

components: { App },

template: ''

})

4、更新vue01\src\components\HelloWorld.vue

v-model="search"

class="search_name"

size="mini"

placeholder="输入姓名查询">

type="text"

@click="onSearch()"

class="el-icon-search">查询

class="el-icon-refresh"

type="text"

@click="refreshData">刷新

class="el-icon-circle-plus-outline"

type="text"

@click="dialogVisible = true">添加

:data="tableData"

highlight-current-row

border

style="width: 100%">

label="编号">

{{ scope.row.userId }}

label="日期">

{{ scope.row.userDate }}

label="姓名">

姓名: {{ scope.row.userName }}

住址: {{ scope.row.userAddress }}

日期:{{ scope.row.userDate }}

{{ scope.row.userName }}

label="住址">

{{ scope.row.userAddress }}

label="操作"

fixed="right"

width="200">

size="mini"

icon="el-icon-edit"

@click="handleEdit(scope.$index, scope.row)">编辑

size="mini"

type="danger"

icon="el-icon-delete"

@click="handleDelete(scope.$index, scope.row)">删除

title="添加"

:append-to-body='true'

:visible.sync="dialogVisible"

width="80%"

:before-close="handleClose">

取 消

确 定

title="编辑"

:append-to-body='true'

:visible.sync="dialogUpdate"

width="80%"

:before-close="handleClose">

取 消

确 定

background

:disabled = "disablePage"

:current-page.sync="currentPage"

small

layout="prev, pager, next"

:page-size="pageSize"

:total="total"

@current-change="handleCurrentChange">

export default {

data() {

return {

ruleForm: {

userId: '',

userName: '',

userDate: '',

userAddress: ''

},

rules: {

userName: [

{ required: true, message: '请输入姓名', trigger: 'blur' },

{ min: 2, max: 7, message: '长度在 2 到 7 个字符', trigger: 'blur' }

],

userAddress: [

{ required: true, message: '请输入住址', trigger: 'blur' },

{ min: 5, message: '长度大于 5 个字符', trigger: 'blur' }

],

},

tableData: [],

search: '',

dialogVisible: false,

dialogUpdate: false,

pageSize: 5,

currentPage: 1,

total: 0,

disablePage: false

}

},

methods: {

handleEdit(index, row) {

this.dialogUpdate = true;

this.ruleForm = Object.assign({}, row); //这句是关键!!!

},

handleDelete(index, row) {

console.log(index, row);

this.$confirm('删除操作, 是否继续?', '提示', {

confirmButtonText: '确定',

cancelButtonText: '取消',

type: 'warning'

}).then(() => {

let postData = this.qs.stringify({

userId: row.userId,

});

this.axios({

method: 'post',

url:'/delete',

data:postData

}).then(response =>

{

this.getPages();

this.currentPage = 1;

this.axios.post('/page').then(response =>

{

this.tableData = response.data;

}).catch(error =>

{

console.log(error);

});

this.$message({

type: 'success',

message: '删除成功!'

});

console.log(response);

}).catch(error =>

{

console.log(error);

});

}).catch(() => {

this.$message({

type: 'info',

message: '已取消删除'

});

});

},

handleClose(done) {

this.$confirm('确认关闭?')

.then(_ => {

done();

})

.catch(_ => {});

},

handleCurrentChange() {

console.log(`当前页: ${this.currentPage}`);

let postData = this.qs.stringify({

page: this.currentPage

});

this.axios({

method: 'post',

url:'/page',

data:postData

}).then(response =>

{

this.tableData = response.data;

}).catch(error =>

{

console.log(error);

});

},

cancel() {

this.dialogUpdate = false;

this.dialogVisible = false;

this.emptyUserData();

},

emptyUserData(){

this.ruleForm = {

userName: '',

userDate: '',

userAddress: ''

}

},

addUser() {

let postData = this.qs.stringify({

userDate: this.ruleForm.userDate,

userName: this.ruleForm.userName,

userAddress: this.ruleForm.userAddress

});

this.axios({

method: 'post',

url:'/insert',

data:postData

}).then(response =>

{

this.axios.post('/page').then(response =>

{

this.tableData = response.data;

this.currentPage = 1;

this.$message({

type: 'success',

message: '已添加!'

});

}).catch(error =>

{

console.log(error);

});

this.getPages();

this.dialogVisible = false

console.log(response);

}).catch(error =>

{

console.log(error);

});

},

updateUser() {

let postData = this.qs.stringify({

userId: this.ruleForm.userId,

userDate: this.ruleForm.userDate,

userName: this.ruleForm.userName,

userAddress: this.ruleForm.userAddress

});

this.axios({

method: 'post',

url:'/update',

data:postData

}).then(response =>

{

this.handleCurrentChange();

this.cancel();

this.$message({

type: 'success',

message: '更新成功!'

});

console.log(response);

}).catch(error =>

{

this.$message({

type: 'success',

message: '更新失败!'

});

console.log(error);

});

},

onSearch() {

let postData = this.qs.stringify({

userName: this.search

});

this.axios({

method: 'post',

url: '/ListByName',

data: postData

}).then(response =>

{

this.tableData = response.data;

this.disablePage = true;

}).catch(error =>

{

console.log(error);

});

},

getPages() {

this.axios.post('/rows').then(response =>

{

this.total = response.data;

}).catch(error =>

{

console.log(error);

});

},

refreshData() {

location.reload();

}

},

created() {

/*this.axios.get('static/user.json').then(response =>

{

this.tableData = response.data.tableData;

this.total = response.data.tableData.length;

// console.log(JSON.parse(JSON.stringify(response.data))['tableData'])

});*/

this.axios.post('/page').then(response =>

{

this.tableData = response.data;

}).catch(error =>

{

console.log(error);

});

this.axios.post('/rows').then(response =>

{

this.total = response.data;

}).catch(error =>

{

console.log(error);

});

},

}

.search_name{

width: 200px;

}

.pages{

margin: 0px;

padding: 0px;

text-align: right;

}

前后端整合

方式一:

在vue01\config\index.js文件中配置proxyTable{},如下:

proxyTable: {

'/': {

target:'http://localhost:8081', // 你请求的第三方接口

changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题

pathRewrite:{ // 路径重写,

'^/': '' // 替换target中的请求地址

}

}

},

方式二:

在vue-cli项目根目录执行命令npm run build,编译完成后将dist/static文件夹copy至springboot项目的src/main/resources/static目录下然后直接启动springboot项目就OK了。

实现效果

6e7cbaa824af1303274224cacfd8278f.png

b2c69fecaedf3193f27c47cf2eff6b28.png

6075abfa0ca44e01e8ddd6a6b88ed621.png

8c1b6ae6a043c40e0ebbbb5ebe28e60f.png

3064d9884a4ae76fe2bef47c1359bdea.png

2e54dd8a5a89e0f96ff24573904aa31c.png

ad65934359ecf2b3138e916ed6944714.png

758ecbac1446976be5baae443632f627.gif

总结

大材小用,✍这篇博客の源码在我的GitHub上。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值