1.新建项目
依次点击 > 文件 > 新建 > 项目 如下图:
选择Spring Initializr项目 注意:创建springboot项目时需要网络
- 按自己的意愿打自己的项目名称
- 选择项目要存放的位置
- 类型选择Maven
- 语言选择Java
- 组一般是com.x x可以按自己喜欢的方式修改
- 工件就是项目名称
- 软件包名称跟组一样
- 项目SDK选择 1.8
- java选择8
- 打包方式为jar
选择好后直接下一步然后完成创建,依赖直接在后面展示
2.查看项目新建完成后的pom文件,添加需要的依赖
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ping</groupId>
<artifactId>SpringCRUD</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringCRUD</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.14</version>
</plugin>
</plugins>
</build>
</project>
3.修改配置文件src/main/resources
修改配置文件本文不使用application.properties文件而使用更加简洁的application.yml文件
目录结构
在application.yml文件里面加入以下内容:
##改变端口号
server:
port: 8081
#配置数据源 datasource
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1?serverTimezone=UTC
username: root
password: root
#mybatis配置
mybatis:
type-aliases-package: org.spring.springboot.domain
mapper-locations: classpath:mapper/*.xml
4.创建表
这是表结构,自行看着创建
5.开始编码操作
5.1在entity包中新建Student.java,使之与数据库中的字段一一对应
@Data注解可以省略getset,用这个注解就能实现
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private String gender;
private int age;
private String address;
private String email;
}
5.2 在mapper包中创建StudentMapper接口
package com.ping.springcrud.mapper;
import com.ping.springcrud.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface StudentMapper {
/**
* 通过名字查找信息
* @param name
* @return 相同名字的信息的集合
*/
public List<Student> findStudentByName(String name);
/**
* 查找所有的员工名字的信息
* @return 所有的员工
*/
public List<Student> ListStudent();
/**
* 分页查询员工信息
* @param starRows
* @return 每一页的员工信息的集合
*/
public List<Student> queryPage(Integer starRows);
/**
* 每一行的个数
* @return
*/
public int getRowCount();
/**
* 插入员工信息
* @param student
* @return 是否成功
*/
public int insertStudent(Student student);
/**
* 通过id删除员工信息
* @param id
* @return 是否成功
*/
public int delete(int id);
/**
* 更新员工信息
* @param student
* @return 是否成功
*/
public int Update(Student student);
}
5.3在service包中创建StudentService.java
package com.ping.springcrud.service;
import com.ping.springcrud.entity.Student;
import com.ping.springcrud.mapper.StudentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class StudentService {
@Autowired
StudentMapper studentMapper;
public List<Student> findStudentByName(String name) {
return studentMapper.findStudentByName(name);
}
public List<Student> ListStudent() {
return studentMapper.ListStudent();
}
public List<Student> queryPage(Integer starRows) {
return studentMapper.queryPage(starRows);
}
public int getRowCount() {
return studentMapper.getRowCount();
}
public Student insertStudent(Student student) {
studentMapper.insertStudent(student);
return student;
}
public int delete(int id) {
return studentMapper.delete(id);
}
public int Update(Student student) {
return studentMapper.Update(student);
}
}
5.4在common包中创建Result.java
package com.ping.springcrud.common;
public class Result<T> {
/*响应码*/
private int code;
/*响应消息*/
private String msg;
/*流水号*/
private String flowcode;
/*数据单元*/
private T data;
public Result() {
}
public Result(T data) {
this.data = data;
}
public Result(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 成功时候的调用
*/
public static <T> Result<T> success(T data) {
return new Result<T>(data);
}
/**
* 失败时候的调用
*/
public static <T> Result<T> error(int code, String msg) {
return new Result<T>(code, msg);
}
}
5.5在controller包中创建StudentController.java
package com.ping.springcrud.controller;
import com.ping.springcrud.entity.Student;
import com.ping.springcrud.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController//项目是前后端分离的,前端返回的数据是json格式,标记注解RestController表示返回的数据都是json格式
@CrossOrigin
public class StudentController {
@Autowired
StudentService studentService;
/**
* 通过员工id删除员工
*
* @param id
* @return
*/
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public Integer delete(Integer id) {
System.out.println(id);
int result = studentService.delete(id);
return result;
}
/**
* 更新员工
*
* @param student
* @return
*/
@RequestMapping(value = "/update", method = RequestMethod.POST)
@ResponseBody
public String update(Student student) {
int result = studentService.Update(student);
if (result >= 1) {
return "修改成功";
} else {
return "修改失败";
}
}
/**
* 插入员工
*
* @param student
* @return
*/
@RequestMapping(value = "/insert", method = RequestMethod.POST)
public Student insert(Student student) {
return studentService.insertStudent(student);
}
/**
* 查询所有
*
* @return
*/
@RequestMapping(value = "/ListStudent")
@ResponseBody
public List<Student> ListStudent() {
return studentService.ListStudent();
}
/**
* 通过名字查询 模糊查询
*
* @param name
* @return
*/
@RequestMapping(value = "/ListByName")
@ResponseBody
public List<Student> ListStudentByName(String name) {
return studentService.findStudentByName(name);
}
/**
* 查询页数
* @param page
* @return
*/
@RequestMapping(value ="/page")
@ResponseBody
public List<Student> page(Integer page) {
int pageNow = page == null ? 1 : page;//传入的页数是null 就查询第一页 否则就根据传入的页数进行查询
int pageSize=5;
int startRows = pageSize * (pageNow - 1);//开始的行数
List<Student> list = studentService.queryPage(startRows);
return list;
}
@RequestMapping(value ="rows")
@ResponseBody
public int rows(){
return studentService.getRowCount();
}
}
5.6在src/main/resources/mapper文件夹下新建StudentMapper的映射文件StudentMapper.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.ping.springcrud.mapper.StudentMapper">
<resultMap id="result" type="com.ping.springcrud.entity.Student">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<result property="gender" column="gender"></result>
<result property="age" column="age"></result>
<result property="address" column="address"></result>
<result property="email" column="email"></result>
</resultMap>
<!--查询所有的方法-->
<select id="ListStudent" resultMap="result">
select * from student;
</select>
<!--通过员工姓名查找员工-->
<select id="findStudentByName" parameterType="String" resultMap="result">
select * from student where name like concat(concat('%',#{name},'%')) order by id desc;
</select>
<!--分页查询-->
<select id="queryPage" parameterType="Integer" resultMap="result">
select * from student order by id desc limit #{startRows},5;
</select>
<!--查询用户的总条数-->
<select id="getRowCount" resultType="Integer">/*返回值类型是Integer*/
select count(*) from student;
</select>
<!--插入数据-->
<insert id="insertStudent" parameterType="com.ping.springcrud.entity.Student">
insert into student(id,`name`,gender,age,address,email)
values(#{id},
#{name,jdbcType=VARCHAR},
#{gender,jdbcType=VARCHAR},
#{age},
#{address,jdbcType=VARCHAR},
#{email,jdbcType=VARCHAR}
)
</insert>
<!--删除-->
<delete id="delete" parameterType="int">
delete from student where id=#{id}
</delete>
<!--更新-->
<update id="Update" parameterType="com.ping.springcrud.entity.Student">
update student
set student.name=#{name},
student.gender=#{gender},
student.age=#{age},
student.address=#{address},
student.email=#{email}
where student.id=#{id};
</update>
</mapper>
5.7启动类
package com.ping.springcrud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringCrudApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCrudApplication.class, args);
}
}
6.vue前端代码
6.1.config包下:index.js文件修改:
proxyTable: {
'/': {
target:'http://localhost:8081', // 你请求的第三方接口
changeOrigin:true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题
pathRewrite:{ // 路径重写,
'^/': '' // 替换target中的请求地址
}
}
},
6.2增删改查主页面:
<template>
<div>
<!--标题-->
<el-form class="title">
vue to complish CRUD
</el-form>
<!--导航栏设计-->
<el-form :inline="true" class="demo-form-inline">
<el-form-item>
<el-input v-model="search" class="search_name" size="mini" placeholder="输入姓名查询"></el-input>
</el-form-item>
<el-form-item>
<el-button type="text" @click="onSearch()" class="el-icon-search">查询</el-button>
</el-form-item>
<el-form-item>
<el-button class="el-icon-refresh" type="text" @click="refreshData">刷新</el-button>
</el-form-item>
<el-form-item>
<el-button class="el-icon-circle-plus-outline" type="text" @click="dialogVisible = true">添加</el-button>
</el-form-item>
</el-form>
<el-table :data="tableData" highlight-current-row border style="width: 100%">
<el-table-column label="编号">
<template slot-scope="scope">
<span>{{ scope.row.userId }}</span>
</template>
</el-table-column>
<el-table-column label="日期">
<template slot-scope="scope">
<i class="el-icon-time hidden-sm-and-down"></i>
<span>{{ scope.row.userDate }}</span>
</template>
</el-table-column>
<el-table-column label="姓名">
<template slot-scope="scope">
<el-popover trigger="hover" placement="right">
<p>姓名: {{ scope.row.userName }}</p>
<p>住址: {{ scope.row.userAddress }}</p>
<p>日期:{{ scope.row.userDate }}</p>
<div slot="reference" class="name-wrapper">
<el-button type="text">{{ scope.row.userName }}</el-button>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="住址">
<template slot-scope="scope">
<span>{{ scope.row.userAddress }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="190">
<template slot-scope="scope">
<el-button size="mini" icon="el-icon-edit" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button size="mini" icon="el-icon-delete" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--添加对话框开始-->
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" size="medium">
<el-dialog title="添加" :append-to-body='true' :visible.sync="dialogVisible" width="50%" :before-close="handleClose">
<el-input type="hidden" v-model="ruleForm.userId"/>
<el-form-item label="时间" prop="userDate">
<el-date-picker type="datetime" placeholder="选择日期" v-model="ruleForm.userDate" style="width: 100%;"></el-date-picker>
</el-form-item>
<el-form-item label="姓名" prop="userName">
<el-input v-model="ruleForm.userName"></el-input>
</el-form-item>
<el-form-item label="住址" prop="userAddress">
<el-input v-model="ruleForm.userAddress"></el-input>
</el-form-item>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel()" size="medium">取 消</el-button>
<el-button @click="addUser()" type="primary" size="medium">确 定</el-button>
</span>
</el-dialog>
</el-form>
<!--添加对话框结束-->
<!--编辑对话框开始-->
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="70px" class="demo-ruleForm" size="medium">
<el-dialog title="编辑" :append-to-body='true' :visible.sync="dialogUpdate" width="50%" :before-close="handleClose">
<el-input type="hidden" v-model="ruleForm.userId"/>
<el-form-item label="时间" prop="userDate">
<el-date-picker type="datetime" placeholder="选择日期" v-model="ruleForm.userDate" style="width: 100%;"></el-date-picker>
</el-form-item>
<el-form-item label="姓名" prop="userName">
<el-input v-model="ruleForm.userName"></el-input>
</el-form-item>
<el-form-item label="住址" prop="userAddress">
<el-input v-model="ruleForm.userAddress"></el-input>
</el-form-item>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel()" size="medium">取 消</el-button>
<el-button @click="updateUser()" type="primary" size="medium">确 定</el-button>
</span>
</el-dialog>
</el-form>
<!--编辑对话框结束-->
<br>
<div class="pages">
<el-pagination background :disabled = "disablePage" :current-page.sync="currentPage" small layout="prev, pager, next" :page-size="pageSize" :total="total" @current-change="handleCurrentChange"></el-pagination>
</div>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
userId: '',
userName: '',
userDate: '',
userAddress: ''
},
rules: {
userName: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{ min: 2, max: 7, message: '长度在 2 到 15 个字符', trigger: 'blur' }
],
userAddress: [
{ required: true, message: '请输入住址', trigger: 'blur' },
{ min: 5, message: '长度大于 3 个字符', 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);
console.log("========"+index);
console.log("======="+row);
this.$confirm('删除操作, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let postData = this.qs.stringify({
userId: row.userId,
});
this.axios({
method: 'post',
url:'http://localhost:8081/delete',
data:postData
}).then(response =>
{
this.getPages();
this.currentPage = 1;
this.axios.post('http://localhost:8081/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:'http://localhost:8081/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:'http://localhost:8081/insert',
data:postData
}).then(response =>
{
this.axios.post('http://localhost:8081/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:'http://localhost:8081/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: 'http://localhost:8081/ListByName',
data: postData
}).then(response =>
{
this.tableData = response.data;
this.disablePage = true;
}).catch(error =>
{
console.log(error);
});
},
getPages() {//-----------------------------------------------------获取页码操作
this.axios.post('http://localhost:8081/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('http://localhost:8081/page').then(response =>
{
this.tableData = response.data;
}).catch(error =>
{
console.log(error);
});
this.axios.post('http://localhost:8081/rows').then(response =>
{
this.total = response.data;
}).catch(error =>
{
console.log(error);
});
},
}
</script>
<style scoped>
.title{
text-align: center;
font-size:35px;
color: #8cc5ff;
font-weight: bold;
}
.search_name{
width: 200px;
}
.pages{
margin: 0px;
padding: 0px;
text-align: right;
}
</style>
6.3router中index.js文件:
import Vue from 'vue'
import Router from 'vue-router'
import Login from "../components/Login";
import HelloWorld from "../components/HelloWorld";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',/*根目录下直接显示*/
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/login',/*根目录下直接显示*/
name: 'login',
component: Login
}
]
})
6.4App.vue文件:
<template>
<div id="app">
<el-row type="flex" justify="center">
<el-col :xs="24" :sm="22" :md="20" :lg="20" :xl="18">
<router-view/>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: 'App',
data(){
return{
}
},
methods:{
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 0px;
padding: 0px;
}
</style>
6.5main.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: '<App/>'
})
项目在这里就完成了
项目效果: