SpringBoot整合SSM(纯注解开发)
1.使用技术
开发环境 | IDEA 2021.2 |
---|---|
数据库 | mysql |
后端 | springboot,mybatis |
前端 | vue,elementUI,js |
2.建表
创建一个users的表,具体字段如下:uid设置为主键且自增
3.创建springboot工程
3.1 :选择Spring Initializr,然后更改jdk版本
3.2:选择需要的起步依赖
3.3:点击finish,项目创建完成
创建完成之后,pom.xml文件详情:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring_ssm</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.4:完成application.yml的相关配置
server:
port: 8080
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db4
username: root
password: 1234
#驼峰命名法
mybatis:
configuration:
map-underscore-to-camel-case: true
4 .后端
项目结构
4.1: 编写实体类
我用的是lombok插件,lombok会帮我们创建成员变量的getter和setter方法,toString,equals方法,可以简化开发,只需在pom.xml中加入这个依赖即可
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
User实体类
package com.example.pojo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Integer uid;
private String username;
private String password;
private String nickname;
private Integer gender;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birthday;
public User() {
}
public User(Integer uid, String username, String password, String nickname, Integer gender, Date birthday) {
this.uid = uid;
this.username = username;
this.password = password;
this.nickname = nickname;
this.gender = gender;
this.birthday = birthday;
}
}
4.2: 编写dao层,与数据库进行联系(Mybatis代理)
package com.example.mapper;
import com.example.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
//加上这个注解,springboot可以给接口创建代理对象
@Mapper
public interface UserMapper {
/**
* 添加用户
* @param user
* @return
*/
@Insert("insert into users values(null,#{username},#{password},#{nickname},#{gender},#{birthday})")
int addUser(User user);
/**
* 修改用户
* @param user
* @return
*/
@Update("update users set username=#{username},password=#{password},nickname=#{nickname},gender=#{gender},birthday=#{birthday} where uid=#{uid}")
int update(User user);
/**
* 根据id查询
* @param uid
* @return
*/
@Select("select * from users where uid=#{uid}")
User findById(int uid);
/**
* 删除用户
* @param uid
* @return
*/
@Delete("delete from users where uid=#{uid}")
int deleteById(int uid);
/**
* 查询所有
* @return
*/
@Select("select * from users")
List<User> findAll();
}
4.3: 编写Service接口以及实现类
service接口
package com.example.service;
import com.example.pojo.User;
import java.util.List;
public interface UserService {
int addUser(User user);
int update(User user);
User findById(int uid);
int deleteById(int uid);
List<User> findAll();
}
接口实现类
package com.example.service.impl;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/*
这个注解是为了让spring帮我们创建对象的,
加上这个注解这个实体类对象就会加入到aoc容器中
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public int addUser(User user) {
return userMapper.addUser(user);
}
@Override
public int update(User user) {
return userMapper.update(user);
}
@Override
public User findById(int uid) {
return userMapper.findById(uid);
}
@Override
public int deleteById(int uid) {
return userMapper.deleteById(uid);
}
@Override
public List<User> findAll() {
return userMapper.findAll();
}
}
4.4: 编写控制类
package com.example.controller;
import com.example.pojo.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.util.List;
//浏览器上只需要输入/users,然后浏览器会根据请求方式的不同去调用不同的方法
@RequestMapping("/users")
@RestController // 包含了这两个注解 @Controller @ResponseBody响应是数据, 不是页面!!!!!!
public class UserController {
@Autowired
private UserService userService;
/**
* 查询所有
* @return
*/
//替代Servlet, 处理好请求参数, 做好响应(异步的响应!!!!!)
@GetMapping
public Result findAll() {
List<User> all = userService.findAll();
Integer code = all == null ? Code.FIND_ERR : Code.FIND_OK;
String msg = all == null ? "查询失败!!" : "";
Result result=new Result(all,code,msg);
return result;
}
/*
@PathVariable , 专门为restfull这个风格服务, 专门获取路径上的参数,
@RequestParam , 专门为普通参数服务的
@RequestBody , 专门为json服务的, 只要开启json自动转换,
发现是对象, 则会自动将json的参数转成你想要的对象
*/
@GetMapping("/{uid}")
public Result findById(@PathVariable int uid) {
User user = userService.findById(uid);
Integer code = user == null ? Code.FIND_ERR : Code.FIND_OK;
String msg = user == null ? "查询失败!!" : "";
Result result=new Result(user,code,msg);
return result;
}
//DateTimeFormat 针对是 80:/users?birthday=1999-1-1 这种!!
@PostMapping
public Result add(@DateTimeFormat(pattern = "yyyy-MM-dd") @RequestBody User user) {
int row = userService.addUser(user);
Integer code = row > 0 ? Code.ADD_OK : Code.ADD_ERR;
Result result=new Result(row,code);
return result;
}
@PutMapping
public Result update(@RequestBody User user) {
int row = userService.update(user);
Integer code = row > 0 ? Code.UPDATE_OK : Code.UPDATE_ERR;
Result result=new Result(row,code);
return result;
}
@DeleteMapping("/{uid}")
public Result deleteById(@PathVariable int uid) {
int row = userService.deleteById(uid);
Integer code = row > 0 ? Code.DELETE_OK : Code.DELETE_ERR;
Result result=new Result(row,code);
return result;
}
}
Result.java 这个是封装响应结果的,会把结果封装成data(存数据),code(存编码),msg(存消息),这样方便前端人员取数据
package com.example.controller;
import lombok.Data;
@Data
public class Result {
//描述统一格式中的数据
private Object data;
//描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
private Integer code;
//描述统一格式中的消息,可选属性
private String msg;
public Result() {
}
public Result(Object data, Integer code) {
this.data = data;
this.code = code;
}
public Result(Object data, Integer code, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
}
Code接口
package com.example.controller;
public interface Code {
//成功的编码
Integer ADD_OK=20011;
Integer DELETE_OK=20021;
Integer UPDATE_OK=20031;
Integer FIND_OK=20041;
//失败的编码
Integer ADD_ERR=20010;
Integer DELETE_ERR=20020;
Integer UPDATE_ERR=20030;
Integer FIND_ERR=20040;
}
5: 前端
前端结构:
pages里边放的是前端代码
5.1:index.html
运行项目成功之后,会访问默认页面,然后直接跳转到users.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
location.href="/pages/users.html"
</script>
</body>
</html>
5.2:users.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="../plugins/elementui/index.css">
<link rel="stylesheet" href="../plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<div id="app">
<div > <a href="/pages/addUser.html">添加用户</a></div>
<table width="80%" cellspacing="0" border="1" align="center">
<tr>
<th>编号</th>
<th>用户名</th>
<th>密码</th>
<th>昵称</th>
<th>性别</th>
<th>生日</th>
<th>操作</th>
</tr>
<tr v-for="user in list">
<td>{{user.uid}}</td>
<td>{{user.username}}</td>
<td>{{user.password}}</td>
<td>{{user.nickname}}</td>
<td>{{user.gender}}</td>
<td>{{user.birthday}}</td>
<td><a href="#" @click="update(user.uid)">修改</a> | <a href="#" @click="deleteById( user.uid)">删除</a></td>
</tr>
</table>
</div>
<script src="/js/axios-0.18.0.js"></script>
<script src="/js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script>
new Vue({
el: "#app",
data: {
list: []
},
methods: {
//查询所有
findAll() {
axios({
method: "get",
url: "/users"
}).then(resp => {
this.list=resp.data.data;
})
},
deleteById(uid){
this.$confirm("此操作永久删除当前数据,是否继续?","提示",{
type:'info'
}).then(()=>{
axios({
method: "delete",
url: "/users/"+uid
}).then(resp => {
if (resp.data.data>0){
this.$message.success("删除成功");
}else {
this.$message.error("删除失败");
}
}).finally(()=>{
location.href="/pages/users.html"
})
}).catch(()=>{
//3.取消删除
this.$message.info("取消删除操作");
})
},
//分页查询
changeCurrentPage(currentPage){
//修改模型
this.currentPage=currentPage;
this.findAll()
},
update(uid){
location.href = "/pages/update.html?"+uid
}
},
mounted() {
//发送异步请求
this.findAll()
}
});
</script>
</body>
</html>
5.3:addUser.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎注册</title>
<style>
a {
color: red;
font-size: 20px;
}
</style>
</head>
<body>
<div id="container">
<form action="#" method="post">
<div>
<label for="username"> 用户名: </label>
<!-- 文本框 -->
<input type="text" name="username" id="username" v-model="user.username">
</div>
<div>
<label for="password">密码: </label>
<!-- 密码框 -->
<input type="password" name="password" id="password" v-model="user.password">
</div>
<div>
<label for="nickname">昵称: </label>
<!-- 密码框 -->
<input type="text" name="nickname" id="nickname" v-model="user.nickname">
</div>
<div>
<label>性别: </label>
<!-- 密码框 -->
<input type="radio" name="gender" value="0" v-model="user.gender"> 男
<input type="radio" name="gender" value="1" v-model="user.gender"> 女
</div>
<div>
<label for="birthday">生日: </label>
<!-- 密码框 -->
<input type="date" name="birthday" id="birthday" v-model="user.birthday">
</div>
</form>
<div>
<button id="sub" @click="addUser()" value="添加"></button>
</div>
</div>
<script src="/js/axios-0.18.0.js"></script>
<script src="/js/vue.js"></script>
<script>
new Vue({
el:"#container",
data:{
user:{}
},
methods:{
addUser(){
//执行异步请求
axios({
method:"post",
url:"/users",
data:this.user
}).then(resp=>{
if (resp.data.data>0){
alert("添加成功")
location.href="/pages/users.html"
}else {
alert("添加失败")
}
})
}
}
})
</script>
</body>
</html>
5.4:update.html
进行修改操作首先需要回显数据,然后再删除,这里就需要当点击修改按钮的时候 ,获取这一行的id,然后在users.html中写一个异步请求,把id传到update.html。
users.html中的异步请求
update(uid){
location.href = "/pages/update.html?"+uid
}
update.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎修改</title>
<style>
a {
color: red;
font-size: 20px;
}
</style>
</head>
<body>
<div id="container">
<form action="#" method="post">
<div>
<label for="username"> 用户名: </label>
<!-- 文本框 -->
<input type="text" name="username" id="username" v-model="user.username">
</div>
<div>
<label for="password">密码: </label>
<!-- 密码框 -->
<input type="password" name="password" id="password" v-model="user.password">
</div>
<div>
<label for="nickname">昵称: </label>
<!-- 密码框 -->
<input type="text" name="nickname" id="nickname" v-model="user.nickname">
</div>
<div>
<label>性别: </label>
<!-- 密码框 -->
<input type="radio" name="gender" value="0" v-model="user.gender"> 男
<input type="radio" name="gender" value="1" v-model="user.gender"> 女
</div>
<div>
<label for="birthday">生日: </label>
<!-- 密码框 -->
<input type="date" name="birthday" id="birthday" v-model="user.birthday">
</div>
</form>
<div>
<button id="sub" @click="update()">修改</button>
</div>
</div>
<script src="/js/axios-0.18.0.js"></script>
<script src="/js/vue.js"></script>
<script>
new Vue({
el: "#container",
data: {
user: {}
},
methods: {
update() {
//执行异步请求
axios({
method: "put",
url: "/users",
data: this.user
}).then(resp => {
if (resp.data.data > 0) {
alert("修改成功")
location.href = "/pages/users.html"
} else {
alert("修改失败")
}
})
}
},
//一加载到这个页面就按前台创传过来的id查询,然后再把数据回显在输入框中
mounted() {
let search = location.search;
let id = search.substring(1);
axios({
method: "get",
url: "/users/"+id
}).then(resp=>{
this.user=resp.data.data
})
}
})
</script>
</body>
</html>
6: 运行结果
运行springboot的启动类开启服务器,控制台出现这个表示服务器开启成功
users.html运行界面