SpringBoot+Mybatis+MySQL+Vue实现CRUD+分页
一:项目展示
效果展示如下:
首页:
修改:
添加:
删除:
二:创建项目
1:创建后端代码
左侧导航栏选择Spring Initializr
点击下一步,选择Spring Web和Mysql Driver依赖如下图:
点击创建即可:
配置文件源码:
在resources下创建application.yml
配置文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | ##改变端口号 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里面更改即可)依赖如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | <?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
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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:
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 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:
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 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
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <?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
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 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 i vue-router@3.5.2 -S;npm i element-ui; npm install axios如下图
首先输入:npm-install
以上下载依赖安装成功后,记得在main.xml里面引入依赖:
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import Vue from 'vue' import App from './App.vue' import router from './router' import VueRouter from 'vue-router' // 前后端分离,必须装配这两个1.引入axios import axios from 'axios' // 引入elementUI import ElementUi from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import store from 'core-js/internals/shared-store' Vue.config.productionTip = false // 2.配置axios,Jquery对象$符号开头 Vue.prototype.$http = axios Vue.config.productionTip = false Vue.use(ElementUi, VueRouter) new Vue({ router, store, render: h => h(App) }).$mount( '#app' ) |
输入启动项目指令
npm run serve
看到该页面,项目创建成功
1:配置vue.config.js:
源码:
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ lintOnSave: false, // 关闭eslint校验 transpileDependencies: true, devServer: { open: true, // 自动打开 port: 8081, // 设置端口号 host: '127.0.0.1', // 设置host proxy: { '/api': { target: 'http://localhost:8081', changeOrigin: true, chunkOrigins: true, pathRewrite: { '^/api': '' } } } } })
开始编写crud页面
创建首页vue界面,index.vue
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | <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) { const 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( '取消' )x }) }, 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> |
配置index路由:
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import Vue from 'vue' import VueRouter from 'vue-router' import index from '../components/index.vue' Vue.use(VueRouter) const routes = [ { path: '/' , name: 'index' , component: index } ] const router = new VueRouter({ routes }) export default router |
创建修改vue界面,update
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <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路由:
源码:
import Vue from 'vue' import VueRouter from 'vue-router' import index from '../components/index.vue' import update from '@/components/update.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'index', component: index }, { path: '/update', name: 'update', component: update } ] const router = new VueRouter({ routes }) export default router
创建添加vue界面,add.vue
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <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路由
源码:
import Vue from 'vue' import VueRouter from 'vue-router' import index from '../components/index.vue' import update from '@/components/update.vue' import add from '@/components/add.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'index', component: index }, { path: '/update', name: 'update', component: update }, { path: '/add', name: 'add', component: add } ] const router = new VueRouter({ routes }) export default router
由于删除是通过触发按钮进行操作的,所以删除没有单独的页面,删除功能在index界面。
本文来自博客园,作者:{Tyr_Header)},转载请注明原文链接:{https://www.cnblogs.com/ForTryHeader/}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~