图书管理系统(vue2 + springboot +mybatis-Plus)前后端分离项目

本人是大一在校学生,代码基本上是原创的,也有些写的不好的地方希望大佬轻点喷我,

本教学致力于让零基础的保姆级教学

准备阶段

学习vue2 , spring-boot ,mybatis-plus 的知识

如果你不会的话虽然我会解释我的代码是什么意思但是也是会稍微的有些看不懂的。
源码链接:https://www.aliyundrive.com/s/LU2b9bRUj6P

前端开发软件

HbuilderX

下载链接:https://www.dcloud.io/hbuilderx.html

后端开发软甲

后端开发软件

idea2021.2.1

下载链接: https://www.jetbrains.com/zh-cn/idea/download/other.html

https://www.aliyundrive.com/s/75V3q5qnocf

我这边是建议idea的版本要比我这个2021的要高,不然的话在创建spring-boot项目会因为不明原因而报错 (个人感觉可能是maven的版本过低)

navicat版本随意

vue2脚手架环境

node18.16.0

下载链接:https://nodejs.org/en

如果版本不对也没关系 跟这个差不多能跑脚手架就行

由于我也忘了我当时是跟谁学的了如果你环境不会配置的话可以试试下面的那个

https://www.bilibili.com/video/BV1AF411n75c/?spm_id_from=333.337.search-card.all.click&vd_source=b1f35457be23de6eae2651ba33731145



开发教学

前端开发部分

随便找一个你看的顺眼的文件夹 下面是我看的顺眼的
在这里插入图片描述

在窗口输入cmd 然后回车 进入cmd控制平台

在这里插入图片描述

在这里插入图片描述

创建一个vue脚手架2 并且将其命名 为library

在这里插入图片描述

vue create library

如果这里创建不成功 有可能是你没装 脚手架你可以试一下在全局的cmd中输入下面的代码

npm install -g @vue/cli-init

创建完成应该是这样子的

在这里插入图片描述


打开hbuilderx 利用和builderx 打开我们刚才创建的文件夹

在这里插入图片描述

运行下面的终端并且输入 npm run serve 来测试你的脚手架是否安装完毕 Ctrl+C可以关闭

在这里插入图片描述
在这里插入图片描述

如果是下面这样就是启动成功

在这里插入图片描述

下载各种组件 vuex vue-router element-ui axios

npm i vuex@3
npm i vue-router@3
npm i element-ui
npm i axios

在这里插入图片描述


创建vuex 与 vue-router 的文件 并且创建其对应的js文件

在这里插入图片描述


配置store 的js文件 和 router的文件

//引入vue
import Vue from 'vue'
//引入vuex
import VueX from 'vuex'
//使用vuex
Vue.use(VueX)
//创建一个action 用于响应动作
const actions={
    
    }
//创建用于操作数据的state的mutation
const mutations={
    
    }
//创建用于储存数据的state
const state= {
    
    }
//创建stroe
export default new VueX.Store({
    
    
	actions,
	mutations,
	state
})
//导入reouter
import VueRouter from 'vue-router'
//引入组件

//创建router
export default new VueRouter({
    
    
	routes:[
		
	]
})

配置main.js

import Vue from 'vue'
import App from './App.vue'

//导入vuex 与 store
import Vuex from 'vuex'
import store from './store/index.js'

//导入 vue-router 与  router
import VueRouter from 'vue-router'
import router from './router/index.js'

//引入axios 
import axios from 'axios'

Vue.config.productionTip = false
//使用vuex
Vue.use(Vuex)
//使用vue-router
Vue.use(VueRouter)
//使用axios
Vue.prototype.$axios = axios

new Vue({
    
    
  render: h => h(App),
  store,
  router
}).$mount('#app')


创建两个组件 一个起名为 HomeNav.vue 另一个起名为 LogIn.vue

在这里插入图片描述

并且在js中分别暴露

	export default{
    
    
		name:'HomeNav',
	}
	export default{
    
    
		name:'Log

在App .vue中引用

<template>
  <div id="app">
		<HomeNav />
		<LogIn />
  </div>
</template>

<script>
import HomeNav from './components/HomeNav.vue'
import LogIn from './components/LogIn.vue'

export default {
    
    
  name: 'App',
  components: {
    
    
		HomeNav,
		LogIn,
		
  }
}
</script>

在 store中设置一个拥有返回布尔值的变量
在这里插入图片描述

在app.vue中使用这个值开控制登录是否成功

在这里插入图片描述

这两行的意思是 如何state中的isLogin为true就显示登录界面

如果为fales就显示主页

正式设置LogIn.vue的组件

先在main中引入element-ui和使用

//引入element-ui 中的部分组件 与css
import {
    
    
	Container,
	Button ,
	Input,
	Form,
	FormItem,
	Header,
	Main
	} from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';


//使用element-ui的组件
Vue.use(Container)
Vue.use(Button)
Vue.use(Input)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Header)
Vue.use(Main)

设置login.vue中的

<!-- 创建外部组件的盒子 -->
<div>
<!-- 设置外容器 -->
<el-container class="outer" >
	<!-- 设置头部 主要是让其空出一块 -->
	<el-header></el-header>
	<!-- 设置主要的容器 -->
	<el-main >
		<!-- 设置分栏布局 让其中的元素能居中 -->
		<el-row type="flex" justify='center' align='middle'>
			<!-- 利用element-ui 创建一个表单 -->
			<el-form ref="form" >
				<!-- 创建表单中的元素 标题 -->
				<el-form-item>
					<p style=" color: #409EFF; font-size: 20px;">图书馆管理系统</p>
				</el-form-item>
				<!-- 设置输入框 让其绑定下方的user.name -->
				<el-form-item   >
					<el-input v-model="user.name" placeholder="请输入用户名称" size="medium"></el-input>
				</el-form-item>
				<el-form-item >
					<el-input v-model="user.password" placeholder="请输入用户密码"></el-input>
				</el-form-item> 
				<el-form-item >
					<!-- 设置登录和注册的按钮 -->
					<el-button type="primary" @click="login()">登录</el-button>
					<el-button type="primary" @click="setUser()">注册</el-button>
				</el-form-item>
			</el-form>
		</el-row>
	</el-main>
</el-container>
</div>

设置下方

.el-main {
    
    
	height: 100%;
	border: 1px solid #fffcf3;
	background-color: #fffcf3;
	width: 350px;
}
.el-row {
    
    
	height: 100%;
}
.outer {
    
    
	height: 100%;
	width: 100%;
	align-items: center;
}

设置js中的代码

export default{
    
    
	name:'LogIn',
	data() {
    
    
		return{
    
    
			// 设置绑定的用户姓名和密码
			user:{
    
    
				name:'',
				password:''
			}
		}
	},
	methods:{
    
    
		//设置登录事件
		login(){
    
    
			
		},
		setUser(){
    
    }
	}
}

后端数据接口

打开idea点击创建项目

在这里插入图片描述

创建一个spring-boot项目

在这里插入图片描述

选择thymeleaf 和 springweb的依赖

在这里插入图片描述

在pom.xml中导入以下的依赖

<!--导入mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!--导入json-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

<!--导入自动装配-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.16</version>
</dependency>
<!--导入数据库驱动依赖 (按照自己的数据的版本来导入)-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.32</version>
</dependency>

打开navicat设计数据库中的表单

在这里插入图片描述

再设计书籍的表单

在这里插入图片描述



再打开我们的idea

在resources中创建一个application.yml文件

在这里插入图片描述

并且在其中配置mybatis-plus

spring:
  datasource:
    username: root
    password: 1234
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///first_web

username —> 用户名

password —> 用户密码

url ----> 数据的名称

开始分层创包

在这里插入图片描述


在pojo层中创建一个一个user

并且在其中声明一个username 与password 并且用@Data注解实现自动装配

package com.example.library.pojo;
import lombok.Data;
/*这个注解用于自动装配*/
@Data
/*这里的User是数据库中的表的名称 
*   如果你的表明使用了 '_' (下划线) 可以利用驼峰命名发来设计类名 
*                               如 tb_user ---> TbUser
* */
public class User {
    
    
//   这是表中的结构名称 表中的结构是什么类型就设计什么类型
    private String username;
    private String password;
}

如果你这里不能使用@Data自动装配 可以看一下是否导入了正确的依赖,如果实在不行的话就用传统的方法

在下面写上getter and setter

在dao层中创建一个UserMapper的接口

package com.example.library.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.library.pojo.User;
import org.springframework.stereotype.Repository;
/*这个注解的意思是 将这个类交给springboot接管*/
@Repository
/*配置mybatis-plus的映射文件*/
public interface UserMapper extends BaseMapper<User> {
    
    
}

在(xxx)Application中设置扫描包

package edu.cvit.loginproject;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
//拥有设置过滤类
@ServletComponentScan
//用于扫描mabatis-plus 的映射文件
@MapperScan("edu.cvit.loginproject.dao.mapper")
@SpringBootApplication
public class LoginprojectApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(LoginprojectApplication.class, args);
    }

}

在dao层中创建一个user包在其中创建一个名为UserDao的接口

public interface UserDao {
    
    
    /*定义一个抽象的方法 
    * 这个方法的目的是 遍历数据库中的 数据看看其是否有对用的用户名
    *                           如果有就返回一个user
    *                           无则返回null
    * */
    public User checkUser(String username);
}

在dao层中创建创建一个名为UserDaoImp的实现类

package com.example.library.dao.user;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.library.dao.mapper.UserMapper;
import com.example.library.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/*创建一个UserDao的实现类
并且将这个实现类交给springboot接管*/
@Repository
public class UserDaoImp implements UserDao{
    
    
    /*让springboot 自动帮我们注入usermapper类*/
    @Autowired
    UserMapper userMapper;
    @Override
    public User checkUser(String username) {
    
    
        /*创建一个条件构造器*/
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        /*给这个条件构造器添加一个条件*/
        wrapper.eq("username" ,username);
        /*查询数据库 如果有符合条件的数据就以user的形式返回 否则就返回null*/
        return userMapper.selectOne(wrapper);
    }
}

在service层中创建一个UserService接口用于定义抽象类

package com.example.library.service.user;

public interface UserService {
    
    
    /*定义一个抽象方法 将user类转换为Json格式*/
    public String UserToJSONString(String username);
}

在service层创建一个UserServiceImp接口用于实现UserService

package com.example.library.service.user;

import com.alibaba.fastjson.JSON;
import com.example.library.dao.user.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/*创建一个UserService的实现类让其交给springboot的管理*/
@Service
public class UserServiceImp implements UserService{
    
    
    /*自动装配dao层*/
    @Autowired
    UserDao userDao;
    @Override
    public String UserToJSONString(String username) {
    
    
        /*
        * JSON.toJSonString 意思为 转换为JSON字符串格式
        * userDao.checkUser 是调用dao层中的方法 来查询是否有符合条件的user
        * */
        return JSON.toJSONString(userDao.checkUser(username));
    }
}

在controller层中创建过滤器

package com.example.library.controller.fiter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import java.io.IOException;

/*设置过滤类*/
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        /*初始化编码  让其可以接收中文字体*/
        servletResponse.setCharacterEncoding("UTF-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
    
    
        Filter.super.destroy();
    }
}

创建一个config层

在这里插入图片描述

package com.example.library.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/*创建一个mvc的配置类*/
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {
    
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    
    
        //跨域设置 由于我的vue-cli的端口号为8080 所以这里设置为8080
        registry.addMapping("/**").allowedOrigins("http://localhost:8080");
    }
}

在controller层中创建一个srvlet包在其中再创建一个UserServlet

package com.example.library.controller.servlet;

import com.example.library.service.user.UserService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
/*将这个类交给springboot管理*/
@RestController
public class userServlet {
    
    
    /*自动装配服务类*/
    @Autowired
    UserService userService;
    /*用于接收get请求 并且返回一json数据类型
    * 这里的username 是前端动态传入的字符串数据类型*/
    @GetMapping("getuser/{username}")
    /*@PathVariable 是将后面的数据绑定到url的占位符中*/
    public void getUser(@PathVariable String username , HttpServletResponse response) throws IOException {
    
    
        /*将json数据写入到网页中*/
        response.getWriter().write(userService.UserToJSONString(username));
    }

}

以上就是后端的第一个接口的写法

在这里插入图片描述


前端部分

点开我们的LogIn.vue 在开始设计我们的登录事件

//设置登录事件
async login(){
    
    
	let _this = this
	/* 设置如果username 为空的情况 */
	if(_this.user.name == ''){
    
    
		//这一行是混子代码 由于vue2 有代码验证 如果这里什么都不填就会报错
		console.log()
	}else{
    
    
		//如果不为空就利用axios获取接口中的值
		_this.$axios.get(_this.UserUrl).then(res=>{
    
    
		})
	}
},

如果你这里报错了 不用担心 大概率是因为上面的箭头函数中的res没有被调用

我们的下一步是 如果密码验证成功了 就将username传入到vuex中方便以后调用


点开我们上文创建好的store中的index.js

//创建一个action 用于响应动作
const actions={
    
    
	setusername(context , username){
    
    
		context.commit('SETUSERNAME',username)
	},
	setislogin(context , islogin){
    
    
		context.commit('SETISLOGIN',islogin)
	}
}
//创建用于操作数据的state的mutation
const mutations={
    
    
	SETUSERNAME(state , username){
    
    
		state.username = username
	},
	SETISLOGIN(state,islogin){
    
    
		state.isLogin = islogin
	}
}
//创建用于储存数据的state
const state= {
    
    
	isLogin:true,
	username:''
}

然后在我们上文axios中的箭头函数下写

	//获取password的值与接口中的值进行对比
	if(_this.user.password == res.data.password){
    
    
		//如果相等就将username储存到vuex中
		_this.$store.dispatch('setusername' , _this.user.name)
		//设置我们主页显示
		_this.$store.dispatch('setislogin' , false)
	}

这样便是是实现的登录的跳转

图书馆主页

前端设置

我们将我们的图书馆主页分为三个大模块

在这里插入图片描述

我们先做我们左边这个模块 我们将其作为导航栏

我们需要先引入element-ui

	Col,
	Menu,
	Submenu,
	MenuItem,
	MenuItemGroup
Vue.use(Col)
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
Vue.use(MenuItemGroup)

在components中创建一个NavMenu.vue组件

将下述的代码粘入其中

下面的代码其实没什么要说的本人也是从element-ui官网粘贴的

<div>
	<el-row >
	<el-col :span="12">
		<el-menu
		default-active="2"
		class="el-menu-vertical-demo"
		background-color="#545c64"
		text-color="#fff"
		active-text-color="#ffd04b
		"  style="width: 200px;" :default-openeds="['1']">
		<el-submenu index="1">
		<template slot="title">
			<i class="el-icon-location"></i>
			<span>首页</span>
		</template>
		<el-menu-item-group>
			<el-menu-item index="1-1">书籍大全</el-menu-item>
		</el-menu-item-group>
		<el-menu-item-group >
			<el-menu-item index="1-2">借阅归还</el-menu-item>
		</el-menu-item-group>
		</el-submenu>
		<el-menu-item index="2">
		<i class="el-icon-menu"></i>
		<span slot="title">管理书籍</span>
		</el-menu-item>
		<el-menu-item index="3" disabled>
		<i class="el-icon-document"></i>
		<span slot="title">关于作者</span>
		</el-menu-item>
	</el-menu>
	</el-col>
</el-row>
</div>

在HomeNav.vue中将我们刚创建好的组件引入并且使用

<!-- 设置各个组件的布局位置 -->
<el-container style="height: 100vh;">
<el-header>Header</el-header>
<el-container >
	<el-aside width="200px">
	<NavMenu />
	</el-aside>
	<el-main>Main</el-main>
</el-container>
</el-container>

这也是在官方的文档中粘贴的

再将组件在HomeNav使用就Ok

在这里插入图片描述

成品为
在这里插入图片描述

下一步使用vue路由 实现左边的main内容的切换

首先在components中创建文明需要的组件

在这里插入图片描述

自己写其中的对应的

export default{
    
    
    name:''
}

打开我们创建的router中的index.js将下面的代码粘如其中

在这里插入图片描述

//导入reouter
import VueRouter from 'vue-router'
//引入组件
import AllBooks from '../components/AllBooks'
import BorrowReturn from '../components/BorrowReturn'
import ManaBooks from '../components/ManaBooks'

//创建router
export default new VueRouter({
    
    
	routes:[
		{
    
    
			path:'/books',
			component:AllBooks
		},
		{
    
    
			path:'/borrow',
			component:BorrowReturn
		},
		{
    
    
			path:'/management',
			component:ManaBooks
		}
	]
})

打开我们之前创建好的NavMenu

将我们的element-ui中的 导航栏与路由器绑定

在这里插入图片描述

这里的

第一步是允许使用路由

第二步是将对应的路由的路径绑定到对应的上

接下来点开我们的HomeNav 在中设计路由器的显示位置

在这里插入图片描述

接下来的前端部分我们先不动

我们先去写后端的接口

有两个接口需要我们去写

  1. 获取所有书籍的接口
  2. 将书籍分页的接口

后端部分

我们先写获取所有书籍的接口


创建一个book类

package com.example.library.pojo;

import lombok.Data;
/*自动装配*/
@Data
public class Book {
    
    
    /*书籍的id*/
    private int bookid;
    /*书籍的名称*/
    private String bookname;
    /*书籍的作者*/
    private String bookauthor;
    /*书籍是否被借阅*/
    private String bookisborrow;
}

由于剩下的步骤跟之前差不多显示所有书籍并且以JSON字符串的形式返回我这里就不讲了,我这里直接给大家讲一下如何分页吧

在我们之前创建的config类中创建一个MybtisConfig

在这里插入图片描述


package com.example.library.config;

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;
/*创建一个spring的注解配置类*/
@Configuration
public class MybatisConfig {
    
    
    /*创建一个bean类*/
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
    
    
        /*创建一个mybatis-plus的拦截器*/
        MybatisPlusInterceptor mpi = new MybatisPlusInterceptor();
        /*给这个拦截器添加一个分页插件*/
        mpi.addInnerInterceptor(new PaginationInnerInterceptor());
        return mpi;
    }
}

在bookDao中创建一个pageBook抽象方法

在这里插入图片描述

在BookDaoImp中创建一个 pagebooks的分页方法并且让其的返回值为集合

public List<Book> pageBooks(int page ,int size) {
    
    
    /*创建一个分页插件 并且往其中放入我们想要查询的页数 以及 每页对少条数据*/
    IPage<Book> bookPage = new Page(page ,size);
    /*设置分页查询*/
    bookMapper.selectPage(bookPage,null);
    /*将分页查询的数据以集合的形式返回*/
    return bookPage.getRecords();
}

在BookService中创建一个pageToJsonString的抽象方法

package com.example.library.service.book;

public interface BookService {
    
    
    /*将拿到的书籍的数据转换为JSON字符串的格式*/
    public String BooksToJsonString();
    /*将拿到的分页的书籍书籍转换为JSON字符串格式*/
    public String pageToJsonString(int page , int size);
}

在BookServiceImp实现类中创建方法

  @Override
  public String pageToJsonString(int page, int size) {
    
    
      return JSON.toJSONString(bookDao.pageBooks(page,size));
  }

在bookServlet中创建一个pageBooks方法

  /*
  * 这里的{page} 与 {size}是占位符的意思
  * */
  @GetMapping("getbooks/{page}&{size}")
  /*@PathVariable 可以将url中的占位符来绑定*/
  public void pageBooks(@PathVariable Integer page , @PathVariable Integer size ,HttpServletResponse response) throws IOException {
    
    
      //将分好页的数据返回为json字符串
      response.getWriter().write(bookService.pageToJsonString(page,size));
  }

在浏览器中 的具体使用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x6F1XIOU-1684150888125)(4d1912bc5a3dd00abcb28650dbc28e7a.png)]

在写一份用于关键字搜索的接口 剩余的步骤与上文一样

  @Override
  public List<Book> pageBooksWrapper(int page, int size, String keyword) {
    
    
      IPage<Book> bookIPage =  new Page(page ,size);
      QueryWrapper<Book> wrapper = new QueryWrapper<>();
      /*设置模糊查询条件*/
      wrapper.like("bookname",keyword);
      bookMapper.selectPage(bookIPage,wrapper);
      return bookIPage.getRecords();
  }


前端部分

我们写完了分页的接口前端只要中axios get请求一下就行

再在main.js中引入下面的element-ui插件

	Table,
	TableColumn,
	Pagination,
	Row,
	PageHeader,


打开我们的AllBooks.vue



<template>
	<div>
		<!-- 这里的data中的三元运算符号
					如果是true 就使用普通分页接口
					如果是false 就使用keyword分页接口
		-->
	<el-table
		:data="isSearch === true ? books:SearchBooks"
		style="width: 100% ;" >
		<el-table-column label="书籍编号" prop="bookid" ></el-table-column>
		<el-table-column label="书籍名称" prop="bookname"></el-table-column>
		<el-table-column label="书籍作者" prop="bookauthor" ></el-table-column>
		<el-table-column prop="bookisborrow" width:"300px">
			<template slot="header" slot-scope='{}'>
			<el-row>
				<el-col :span="14">
					<el-input v-model="search" placeholder="搜索书籍"></el-input>
				</el-col >
				<el-col :span="3.8">
				<el-button icon="el-icon-search" circle @click="Search"></el-button>
				</el-col>
				<el-col :span="3">
					<el-button type="danger" icon="el-icon-delete" circle @click="Reset"></el-button>
				</el-col>
			</el-row>
			</template>
		</el-table-column>
		</el-table>
		<el-pagination
			@current-change='pagechange'
			background
			layout="prev, pager, next"
			:total="1000">
		</el-pagination>
	</div>
</template>

<script>
	export default{
    
    
		name:'AllBooks',
		data() {
    
    
			return{
    
    
				/* 后端接口的数据存放的位置 */
				books:[],
				book:{
    
    
					url:'http://localhost:8081/getbooks/',
					page:1,
					size:5,
				},
				/* inpuit所双向绑定的数据 */
				search:'',
				/* 用于判断启动的分页接口 */
				isSearch:true
			};
		},
		mounted(){
    
    
			if(this.search == ''){
    
    
			/* 创建一个挂载函数 用于获取axios数据 */
			this.$axios.get(this.BookUrl).then(res=>{
    
    
				this.books = res.data
			})
			}
			else{
    
    
				this.$axios.get(this.SearchKeywordsBooks).then(res=>{
    
    
					this.books = res.data
					
				})
			}
		},
		computed:{
    
    
			/* 利用计算属性将url组合在一起 */
			BookUrl(){
    
    
				return this.book.url + this.book.page + '&'+this.book.size;
			},
			/* 利用计算属性来进行过滤 */
			SearchBooks(){
    
    
				return this.books.filter((b)=>{
    
    
					return b.bookname.indexOf(this.search) !== -1
				})
			},
			/* 利用计算属性组合分页接口 */
			SearchKeywordsBooks(){
    
    
				return this.BookUrl + "/" + this.search
			}
		},
		methods:{
    
    
			/* 给分页的按钮绑定点击事件 */
			pagechange(page){
    
    
				/* 将页数更新我们点击到的位置 */
				this.book.page = page
				//如果输入框中的内容为空就获取正常分页接口
				if(this.search == ''){
    
    
					this.$axios.get(this.BookUrl).then(res=>{
    
    
					this.books = res.data
				})
				}
				/* 如果不为空就用关键字分页接口 */
				else{
    
    
					this.$axios.get(this.SearchKeywordsBooks).then(res=>{
    
    
						this.books =res.data
					})
				}
			},
			/* 设置搜索按钮的点击事件 */
			Search(){
    
    
				/* 设置接口为关键字分页接口 */
				this.isSearch = false
				this.$axios.get(this.SearchKeywordsBooks).then(res=>{
    
    
					this.books = res.data
				})
			},
			/* 设置重置按钮的点击事件 */
			Reset(){
    
    
				/* 设置接口为普通分页接口 */
				this.isSearch = true
				this.book.page = 1
				this.$axios.get(this.BookUrl).then(res=>{
    
    
					this.books = res.data
				})
				/* 将搜索框清空 */
				this.search = ''
			}
		},
	}
</script>

书籍管理

完成的目标是实现书籍的增删改查功能

我们先写前端部分 由于后面的功能都大差不差 所以我这边先给大家演示怎么做一个删除的功能

我会将我的源码传到阿里云盘供大家下载

后端部分

创建一个通过书籍id来删除数据库中的书籍的方法

BookDao中创建一个用于通过id删除的抽象方法

/*定义 一个通过id进行搜索并且删除的方法*/
public void  deleteBook(int bookid);

在BookDaoImp中创建一个

@Override
public void deleteBook(int bookid) {
    
    
    /*创建条件*/
    QueryWrapper<Book> wrapper = new QueryWrapper<>();
    wrapper.eq("bookid",bookid);
    /*通过条件来删除书籍库中的数据*/
    bookMapper.delete(wrapper);
}

剩下的就是业务层跟上面也大差不差所以我直接给大家展示servlet部分吧

/*删除书籍的接口*/
@PostMapping("delectbook/{bookid}")
public void deleteBookId(@PathVariable Integer bookid , HttpServletResponse response){
    
    
    bookService.deleteBookId(bookid);
}

这里是创建了一个只允许post请求

前端部分

打开我们的ManaBooks.vue在表格中添加一个新的项

<el-table-column label="操作" width="150px">
	<template slot-scope="scope">
		<!-- 给按绑定一个事件 -->
		<el-button @click="UpdateBook(scope.row)" type="primary" size="small" >修改</el-button>
		<el-button @click="DeleteBook(scope.row)" type="danger" size="small">删除</el-button>
	</template>
</el-table-column>

给按钮绑定事件

/* 删除的方法 */
DeleteBook(row){
    
    
	let _this = this
	/*设计弹窗拥有让用户确定是否点击按钮*/
	if(window.confirm("是否确认删除吗?")){
    
    
		console.log(row.bookid)
		/* 利用axios来进行Post请求 */
		console.log(_this.book.deleteUrl+ row.bookid )
		_this.$axios.post(_this.book.deleteUrl + row.bookid)
		_this.Reset()
	}
}

剩下的方法制作方法我就不写拉直接看我的源码吧我的源码也会有非常详细的注释

猜你喜欢

转载自blog.csdn.net/XiaoSongDADA/article/details/130691296