SpringBoot+Mybatis+MySQL+Vue实现CRUD+分页

发布时间 2024-01-09 11:08:26作者: Try_Header

一:创建项目

1:创建后端代码

左侧导航栏选择Spring Initializr

 点击下一步,选择Spring Web和Mysql Driver依赖如下图:

 点击创建即可:

配置文件源码:

在resources下创建application.yml

 

 配置文件代码如下:

##改变端口号
server:
  port: 8081

#配置数据源  datasource
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/encryptdb?serverTimezone=UTC
    username: root
    password: root

#mybatis配置
mybatis:
  type-aliases-package: org.spring.springboot.domain
  mapper-locations: classpath:mapper/*.xml

  我所用到的maven(在项目的pom.xml里面更改即可)依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.jl</groupId>
    <artifactId>Crud_Two</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Crud_Two</name>
    <description>Crud_Two</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!--Junit 单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--SpringBoot Test依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.jl.crud.CrudApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

  项目整体结构如下:

 首先在Pojo目录下创建实体类User

 源码:

package com.jl.crud_two.Pojo;

import lombok.Data;

/**
 * @Author Jin
 * @Description
 * @Date 2024/1/6 14:52
 **/
@Data
public class User {
    private Integer id;
    private String name;
    private Integer age;
}

  在Mapper目录下创建UserMapper:

 源码:

package com.jl.crud_two.Mapper;

import com.jl.crud_two.Pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @Author Jin
 * @Description
 * @Date 2024/1/6 14:59
 **/
@Mapper
public interface UserMapper {
    /**
     * 分页查询员工信息
     * @param starRows
     * @return 每一页的员工信息的集合
     */
    public List<User> queryPage(Integer starRows);

    /**
     * 每一行的个数
     * @return
     */
    public int getRowCount();

    /**
     * 插入
     * @param user
     * @return
     */
    public int insertUser(User user);

    /**
     * 通过id删除员工信息
     * @param id
     * @return 是否成功
     */
    public Integer delete(int id);

    /**
     * 更新员工信息
     * @param user
     * @return 是否成功
     */
    public int Update(User user);

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public User byId(Integer id);
}

  在Service目录下创建UserService:

 源码:

package com.jl.crud_two.Service;

import com.jl.crud_two.Mapper.UserMapper;
import com.jl.crud_two.Pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author Jin
 * @Description
 * @Date 2024/1/6 15:09
 **/
@Service
public class UserService {
    @Autowired
    UserMapper userMapper;


    /**
     * 分页
     * @param starRows
     * @return
     */
    public List<User> queryPage(Integer starRows){
        return userMapper.queryPage(starRows);
    }

    /**
     * 每一行的个数
     * @return
     */
    public int getRowCount(){
        return userMapper.getRowCount();
    }

    /**
     * 插入
     * @param user
     * @return
     */
    public User insertUser(User user){
        userMapper.insertUser(user);
       return user;
    }

    /**
     * 通过id删除员工信息
     * @param id
     * @return 是否成功
     */
    public Integer delete(int id){
        return userMapper.delete(id);
    }

    /**
     * 更新员工信息
     * @param user
     * @return 是否成功
     */
    public int Update(User user){
        return userMapper.Update(user);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    public User byId(Integer id){
        return userMapper.byId(id);
    }
}

  在resources目录下创建mapper目录:

 

 在mapper目录下创建UserMapper.xml

 源码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jl.crud_two.Mapper.UserMapper">
    <resultMap id="result" type="com.jl.crud_two.Pojo.User">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
    </resultMap>

    <!--分页查询-->
    <select id="queryPage" parameterType="Integer" resultMap="result">
        select *
        from user
        order by id desc limit #{startRows}, 5;
    </select>

    <!--查询用户的总条数-->
    <select id="getRowCount" resultType="Integer">/*返回值类型是Integer*/
    select count(*)
    from user;
    </select>

    <!--插入数据-->
    <insert id="insertUser" parameterType="com.jl.crud_two.Pojo.User">
        insert into user(name, age)
        values (#{name}, #{age})
    </insert>

    <!--删除-->
    <delete id="delete" parameterType="int">
        delete
        from user
        where id = #{id}
    </delete>

    <!--更新-->
    <update id="Update" parameterType="com.jl.crud_two.Pojo.User">
        update user
        set user.name=#{name},
            user.age=#{age}
        where user.id = #{id};
    </update>

    <!--    根据id查询-->
    <select id="byId" resultMap="result">
        select *
        from user
        where id = #{id}
    </select>
</mapper>

  在Controller目录下创建UserController

 源码:

package com.jl.crud_two.Controller;

import com.jl.crud_two.Mapper.UserMapper;
import com.jl.crud_two.Pojo.User;
import com.jl.crud_two.Service.UserService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author Jin
 * @Description
 * @Date 2024/1/6 15:21
 **/
@RestController
@RequestMapping("/UserController")
public class UserController {
    @Autowired
    UserService userService;

    /**
     * 通过员工id删除员工
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public Integer delete(@Param("id") Integer id) {
        System.out.println(id);

        return userService.delete(id);
    }

    /**
     * 更新员工
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public String update(@RequestBody User user) {
        int result = userService.Update(user);
        if (result >= 1) {
            return "修改成功";
        } else {
            return "修改失败";
        }
    }

    /**
     * 插入员工
     *
     * @param user
     * @return
     */
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    public User insert(@RequestBody User user) {
        return userService.insertUser(user);
    }

    @RequestMapping(value = "/byId")
    @ResponseBody
    public User byId(Integer id) {
        return userService.byId(id);
    }

    /**
     * 查询页数
     *
     * @param page
     * @return
     */
    @RequestMapping(value = "/page", method = RequestMethod.POST)
    @ResponseBody
    public List<User> page(Integer page) {
        int pageNow = page == null ? 1 : page;//传入的页数是null  就查询第一页   否则就根据传入的页数进行查询
        int pageSize = 5;
        int startRows = pageSize * (pageNow - 1);//开始的行数
        List<User> list = userService.queryPage(startRows);
        return list;
    }

    @RequestMapping(value = "rows")
    @ResponseBody
    public int rows() {
        return userService.getRowCount();
    }

}

  后端代码编写完成,随后启动项目

 2:创建vue项目

1:根据自己的需求,在对应的路径,输入cmd,

 

 2:在cmd里面输入:vue ui,如下图:

 3:点击create,开始创建vue项目

 4:点击Create a new project here,开始创建项目,详细操作如下图:

 注意:在创建项目的时候,系统给了3种方式创建项目。

①:默认创建操作都一样,这里以vue2版本为主,

 ②:选择第二个,如下图

 ③:等待系统创建

 ④:出现如下图,就代表这项目已成功创建,在这里可以对项目下载插件

 ⑤:通过开发软件,来启动项目,分别输入指令:npm-install; npm run serve,如下图

首先输入:npm-install

 输入启动项目指令

npm run serve

 看到该页面,项目创建成功

 1:在项目根目录下创建config目录:

 创建index.js

 源码:

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
      '/api':{
        target:'http://localhost:8081',
        changeOrigin:true,
        chunkOrigins:true,
        pathRewrite:{
          '^/api':''
        }
      }
    },

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-


    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

  开始编写crud页面

打开HelloWorld.vue进行编写

 源码:

<template>
  <div align="center">
    <!--tableData存放数据的数组-->
    <el-table
      :data="tableData"
      border
      style="width: 60%">
      <el-table-column
        prop="id"
        label="唯一标识"
        width="120">
      </el-table-column>
      <el-table-column
        prop="name"
        label="名称"
        width="120">
      </el-table-column>

      <el-table-column
        prop="age"
        label="年龄"
        width="120">
      </el-table-column>


      <el-table-column
        fixed="right"
        label="操作"
        width="150">
        <template slot-scope="scope"><!--scope作用域-->
          <!--当前所有字段值-->
          <el-button @click="update(scope.row)"><i class="el-icon-edit"></i></el-button>
          <el-button @click="deleteClick(scope.row)"><i class="el-icon-delete"></i></el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-button @click="addBanner" type="text" size="small">添加</el-button>

    <!-- 分页开始 -->
    <!-- 分页器 -->
    <div class="block" style="margin-top:15px;">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 15, 20, 25]"
        :page-size="pageSize"
        layout="total, prev, pager, next, jumper"
        :total="total">
      </el-pagination>
    </div>
    <!-- 分页结束 -->



  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      tableData: [],//查询所有数组
      id: null,
      delsselection:[],//接收多选的列表
      imageUrl:'',
      // 分页相关数据
      currentPage: 1, // 当前页码
      total: 20, // 总条数
      pageSize: 3 // 每页的数据条数

    }
  },
  mounted(){
    this.getlivestockInfo(1);
  },
methods:{
  // 分页
//每页条数改变时触发 选择一页显示多少行
  handleSizeChange(val) {
    console.log(`每页 ${val} 条`);
    // this.currentPage = 1;
    this.pageSize = val;
  },
  //当前页改变时触发 跳转其他页
  handleCurrentChange(val) {
    console.log(`当前页: ${val}`);
    this.currentPage = val;
    this.getlivestockInfo(val);
  },
  getlivestockInfo(num1){
    var params = new URLSearchParams();
    params.append('pageNum',num1);
    this.$http.post('/api/UserController/page',params)    //补上后台接口即可
      .then(response => {  // 请求成功
        console.log('请求成功');

        console.log(this.tableData);
        // this.currentPage=num1;
        this.total=response.data.length;
        this.tableData=response.data.slice((this.currentPage-1)*this.pageSize,this.currentPage*this.pageSize);
        // console.log(this.tableData.list.length);
      }).catch(error => {  // 请求失败
      console.log('请求失败');
      console.log(error);
    })
  },



  // getAll() {
  //   this.$http.get('/api/StudentController/ListStudent').then(res => {
  //     console.log("res.data==============>", res.data)
  //     this.tableData = res.data
  //   })
  // },
  handleClick(row) {
    console.log("点击查看携带的参数",row)
    this.$router.push({
      path: '/GetOne',
      name: 'GetOne',
      params: {
        id: row.id
      }
    })
  },
  addBanner() {
    this.$router.push({
      path: '/add',
      name: 'add'
    })
  },
  update(row) {
    //跳转页面,携带参数
    this.$router.push({
      //路径 名称 参数
      path: '/update',
      name: 'update',
      params: {
        id: row.id
      }
    })
  },
  deleteClick(row) {
    this.$confirm("确定删除吗?", {type: 'warning'}).then(res => {
      this.$http.post('/api/UserController/delete?id='+row.id).then(res => {
        this.$message.success('true');
        console.log("res.data=======================>", res.data)
        this.getAll();
      })
    }).catch(() => {
      this.$message.info('取消');
    })
  },
  handleSelectionChange(val){
    console.log("打印val的值",val);
    this.delsselection=val;
  },

  uploading() {
    this.$router.push({
      path: '/Fileupload',
      name: 'Fileupload'
    })
  }
},

  created() {
    this.getAll();


  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

  配置HelloWorld.vue路由

打开router目录下的index.js(若没有,创建即可)

 源码:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
  
  ]
})

  创建添加vue页面:add

 源码:

<template>
  <div align="center">
    <el-form :model="banner" status-icon ref="ruleForm" style="width: 20%" label-width="100px" class="demo-ruleForm">
      <el-form-item label="名称" prop="name">
        <el-input v-model.number="formLabelAlign.name"></el-input>
      </el-form-item>


      <el-form-item label="年龄" prop="age">
        <el-input v-model.number="formLabelAlign.age"></el-input>
      </el-form-item>





      <el-form-item>
        <el-button type="primary" @click="add">添加</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>

  </div>

</template>

<script>
export default {
  data(){
    return{
      /*formLabelAlign:[]*/
      formLabelAlign:{
        name:"",
        gender:"",
        age:"",
        address:"",
        email:""
      }
    }
  },
  methods:{
    add(){
      this.$http.post('/api/UserController/insert',this.formLabelAlign).then(res=>{
        console.log("res.data==============>",res.data)
        if (res.status===200){
          this.$router.push({
            path:'/'
          })
        }
      })
    }
  },
  created() {

  }
}
</script>

<style scoped>

</style>

  配置add.vue路由

打开router目录下的index.js

 源码:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import add from "../components/add";
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/add',
      name: 'add',
      component: add
    },
  ]
})

  创建修改vue:update.vue

 源码:

<template>
  <div align="center">
    <el-form :model="banner" status-icon ref="ruleForm" style="width: 20%" label-width="100px" class="demo-ruleForm">
      <el-form-item label="名称" prop="name">
        <el-input v-model.number="formLabelAlign.name"></el-input>
      </el-form-item>


      <el-form-item label="年龄" prop="age">
        <el-input v-model.number="formLabelAlign.age"></el-input>
      </el-form-item>



      <el-form-item>
        <el-button type="primary" @click="update">提交</el-button>
        <el-button>取消</el-button>
      </el-form-item>
    </el-form>

  </div>

</template>

<script>
export default {
  data(){
    return{
      id:null,
      formLabelAlign:{},//接收返回对象
      bannertypes:[],
    }
  },
  methods:{
    getOne(){
      this.$http.get('/api/UserController/byId',{params:{id:this.id}}).then(res=>{
        console.log("res.data查询单个==============>",res.data)
        this.formLabelAlign=res.data
      }).catch(err=>{
        this.$message.error("查询单个错误!")
      })
    },
    // getBannerTypes(){
    //   this.$http.get('/api/banner/getTypes').then(res=>{
    //     this.bannertypes=res.data;
    //   })
    // },
    update(){
      this.$http.post('/api/UserController/update',this.formLabelAlign).then(res=>{
        console.log("res.data修改返回结果==============>",res.data)
        if (res.status===200){
          this.$message.success("修改成功");
          this.$router.push({
            path:'/'
          })
        }else {
          this.$message.error("修改失败");
        }
      })
    }
  },
  created() {
    this.id=this.$route.params.id
    this.getOne()
    // this.getBannerTypes()
  }
}
</script>

<style scoped>

</style>

  配置update.vue路由

打开router目录下的index.js

 源码:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import add from "../components/add";
import update from "../components/update";

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/add',
      name: 'add',
      component: add
    },
    {
      path: '/update',
      name: 'update',
      component: update
    }
  ]
})

  备注:删除由于是通过点击触发,所以没有单独的删除页面,删除功能在HelloWorld.vue里面。到这里vue代码已写完,

测试

三:项目测试(本次是采用前后端分离,运行项目的时候前端和后端要同时启动)

 

 效果展示如下:

首页:

 修改:

 

 添加:

 

 

 删除: