SpringBoot+Vue实现CURD(增删改查)
1.建表
CREATE TABLE `user`(
`id` BIGINT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT NULL COMMENT '姓名',
`age` INT DEFAULT NULL COMMENT '年龄',
`sex` VARCHAR(1) DEFAULT NULL COMMENT '性别',
`address` VARCHAR(255) DEFAULT NULL COMMENT '地址',
`phone` VARCHAR(20) DEFAULT NULL COMMENT '电话',
`create_time` VARCHAR(20) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8
2.设置application.yml
-
(1)数据库在存放项目数据的时候会先用UTF-8格式将数据解码成字节码,然后再将字节码重新使用GBK编码存放到数据库中;
(2)从数据库中取数据的时候,数据库会先将数据按GBK格式解码成字节码,然后再将字节码重新按UTF-8格式编码数据,最后再将数据返回给客户端。
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
hikari:
username: root //账号
password: 123456 //密码
jdbc-url: jdbc:mysql://localhost:3306/zlj?useUnicode=true&characterEncoding=utf-8
3.entity层
- 实体层->数据库在项目中的类,该文件包含实体类的属性和对应属性的set、get方法;
package luti.curd.entity;
import javax.persistence.*;
/**
* @program: CURD
* @description: 实体类
* @author: Mr.Lu
* @create: 2022-09-03 22:17
**/
@Table(name= "user")/*@Table注解的常用选项是 name,用于指明数据库的表名*/
@Entity /*表示其所对应的数据库中的表名*/
public class User {
@Id/*指定表的主键*/
@Column(name =("id"))/*用于指定列的相关属性 name可选,表示数据库表中列的名称。 默认为属性或字段名称*/
@GeneratedValue(strategy = GenerationType.AUTO) /*自增*/
private Long id;
private String name;
private Integer age;
private String sex;
private String address;
private String phone;
@Column(name = "create_time")
private String createTime;
/**
* 作用:1.使代码更灵活 2.使代码更安全
* get,set方法*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}
4.DAO层
- DAO层会调用entity层,DAO中会定义实际使用到的方法,比如增删改查。DAO 层的数据源和数据库连接的参数都是在配置文件中进行配置的,配置文件一般在同层的XML文件夹中。数据持久化操作就是指,把数据放到持久化的介质中,同时提供增删改查操作。
@Repository /*用于将数据访问层 (DAO 层 ) 的类标识为 Spring Bean*/
public interface UserDao extends JpaRepository<User,Long> {
/*自己写了一个模糊查询*/
@Query(value = "select * from user where name like %?1%",nativeQuery = true)
Page<User> findNameLike(String name, Pageable pageRequest);
}
5.service层
- Service层主要负责业务模块的逻辑应用设计。先设计放接口的类,再创建实现的类,然后在配置文件中进行配置其实现的关联
package luti.curd.service;
import luti.curd.dao.UserDao;
import luti.curd.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @program: CURD
* @description: 业务层
* @author: Mr.Lu
* @create: 2022-09-04 02:13
**/
@Service/*说明当前是service类,会自动注入到spring容器中*/
public class UserService {
@Resource
private UserDao userDao;
/**
* 新增和修改
* @param user
*/
public void save(User user){
userDao.save(user);
}
/**
*
* @param id
*/
public void del(Long id){
userDao.deleteById(id);
}
/**
* 根据id查询用户
* @param id
*/
public User findByid(Long id){
return userDao.findById(id).orElse(null);
}
/**
* 分页查询
* @param pageNum
* @param pageSize
* @param name
* @return
*/
public Page<User> findPage(Integer pageNum,Integer pageSize,String name){
Sort sort=Sort.by(Sort.Direction.DESC,"create_time"); /*倒序排序*/
Pageable pageRequest = PageRequest.of(pageNum-1,pageSize,sort);
return userDao.findNameLike(name,pageRequest); /*模糊查询*/
}
}
6.Controller层
- Controller层负责具体的业务模块流程的控制,controller层负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
package luti.curd.controller;
import luti.curd.common.Result;
import luti.curd.entity.User;
import luti.curd.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @program: CURD
* @description: 控制层
* @author: Mr.Lu
* @create: 2022-09-04 02:38
**/
@RestController /*接口中所有方法返回JSON数据格式*/
@RequestMapping("/user") /*设置映射请求的请求路径的初始信息*/
public class UserController {
@Resource
private UserService userService;
/**
* 新增
* @param user
* @return
*/
@PostMapping
public Result add(@RequestBody User user){ /*这个注解代表接受JSON对象,把JSON对象转换成User对象*/
userService.save(user); /*if 新增 没有id,数据库会自增id else 更新 会传一个 id */
return Result.success();
}
/**
* 更新
* @param user
* @return
*/
@PutMapping
public Result update(@RequestBody User user){
userService.save(user);/*同上*/
return Result.success();
}
/**
* 删除用户
* @param id
* @return
*/
@DeleteMapping("/{id}")
public void delete(@PathVariable("id") Long id){
userService.delete(id);
}
/**
* 根据id查询
* @param id
* @return
*/
@GetMapping("/{id}")
public Result<User> findById(@PathVariable Long id){
return Result.success(userService.findByid(id));
}
/**
* 查询所有信息
* @return
*/
@GetMapping
public Result<List<User>> findAll(){
return Result.success(userService.findAll());
}
/**
* 分页模糊查询
* @param pageNum
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public Result<Page<User>> findPage(@RequestParam(defaultValue = "1")Integer pageNum,
@RequestParam(defaultValue = "10")Integer pageSize,
@RequestParam(required = false)String name){
return Result.success(userService.findPage(pageNum,pageSize,name));
}
}
7.index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户信息</title>
<!-- 引入样式 -->
<link rel="stylesheet" href="element.css">
</head>
<body>
<div id="wrapper" style="width: 80%; margin: 0 auto">
<p>用户信息:</p>
<!--首先每行使用<el-row>标签标识,然后每行内的列使用<el-col>标识,至于每列整行的宽度比例,则使用:span属性进行设置。-->
<el-row>
<el-col :span="6" style="margin-bottom: 10px">
<el-button type="primary" @click="add">新增</el-button>
<el-input v-model="name" style="width: 70%" @keyup.enter.native="loadTable(1)"></el-input><!--回车页面进行一次刷新-->
</el-col>
</el-row>
<!-- 表单提交是开发中非常常见的功能,也是和用户交互的重要手段:
比如用户在登录、注册时需要提交账号密码;比如用户在检索、创建、更新信息时,需要提交一些数据;
这些都要求我们可以在代码逻辑中获取到用户提交的数据,我们通常会使用v-model指令来完成-->
<!--表格列表-->
<!--这里的prop就是用来从每一个对象中取出属性名为date的 属性值。-->
<!--label:决定当前列显示出的标题-->
<!--width: 用来设置列的宽度。如果不设置,它会自适应。-->
<el-table
:data="page.content"
stripe
style="width: 100%">
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="age"
label="年龄"
width="180">
</el-table-column>
<el-table-column
prop="sex"
label="性别">
</el-table-column>
<el-table-column
prop="address"
label="地址">
</el-table-column>
<el-table-column
prop="phone"
label="电话">
</el-table-column>
<el-table-column
prop="createTime"
label="创建时间">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="100">
<!-- 1. slot-scope是固定写法
2. scope理解为变量,并不一定需要固定这个名字,template组件会自动将渲染本行需要的数据
3. 传给scope,其中scope.row就表示当前行的数据,它对应数据源中的某个对象。这里的row是固定写法-->
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" size="small" circle @click="edit(scope.row)"></el-button>
<el-button type="danger" icon="el-icon-delete" size="small" cricle @click="del(scope.row.id)"></el-button>
</template>
</el-table-column>
</el-table>
<el-row type="flex" justify="center" style="margin-top: 10px">
<!--分页组件-->
<el-pagination
layout="prev ,pager,next"
:page-size="pageSize"
:current-page="pageNum"
@prev-click="loadTable"
@current-change="loadTable"
@next-click="loadTable"
: total="page.totalElements">
</el-pagination>
</el-row>
<!--弹窗-->
<el-dialog title="用户信息" : visible.sync="dialogVisible" width="30%">
<el-form ref="form" :model="form" lable-width="80px">
<el-form-item label="用户名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="年龄">
<el-input v-model="form.age"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-input v-model="form.sex" label="男">男</el-input>
<el-input v-model="form.sex" label="女">女</el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="form.address"></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.phone"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="save">确定</el-button>
</span>
</el-dialog>
</div>
<!--引入组件库-->
<script src="jquery.min.js"></script>
<script src="vue.js"></script>
<script src="element.js"></script>
<script>
new Vue({
el: '#wrapper' ,
data: {
page: {},
name: '',
pageNum: 1,//页数
pageSize: 8,//每页显示的行数
dialogVisible: false, //关闭弹出
form: {} //获取表单数据
},
// created() 这个函数是vue内置函数,当组件创建完成自动触发的一个函数
// created函数表示:b组件创建完成
// 这个创建的意思是:在浏览器访问项目的时候开始创建
created(){
this.loadTable(this.pageNum);
},
methods: {
loadTable(num) {
this.pageNum=num;
$.get("/user/page?pageNum" + this.pageNum + "&pageSize" + this.pageSize + "&name=" + this.name).then(res =>{
this.page=res.data;
});
},
add(){
this.dialogVisible=true;
this.form= {};
},
edit(row){
this.form= row;
this.dialogVisible=true;
},
save(){
let data=JSON.stringify(this.form); //转JSON字符串
if(this.form.id){
//编辑
$.ajax({
url: '/user',
type: 'put',
contentType: 'application/json',
data: data
}).then(res =>{
if(res.code === '0'){
this.dialogVisible=false;
this.loadTable(1);
}else{
console.error("没取到数据");
error.message("错误");
}
})
}else{
//新增
$.ajax({
url: '/user',
type: 'post',
contentType: 'application/json',
data: data
}).then(res =>{
this.dialogVisible=false;
this.loadTable(1);
})
}
},
del(id){
$.ajax({
url: '/user/'+id,
type: 'delete',
contentType: 'application/json'
}).then(res =>{
ths.loadTable(1);
})
}
}
})
</script>
</body>
</html>
8.温馨提示
- 超级基础的增删改查操作;
- 脚手架和前端文件:https://pan.baidu.com/s/1wbyNeK6yHXW57uMbFGnqVw 提取码:y562
- 前端使用的是element组件 :https://element.eleme.cn/