| 这个作业属于哪个课程 | 软件工程实践2022年春-F班 |
|---|---|
| 这个作业要求在哪里 | 软件工程实践总结&个人技术博客 |
| 这个作业的目标 | 个人技术博客 |
| 其他参考文献 | CSDN、博客园 |
- 一、技术概述
- 二、技术详述
- 1.先了解一下具体的实现原理(~~如果不想看可以直接跳过~~ )
- 2.准备阶段
- 3.编写实体层
- 4.编写mapper(dao)
- 5.编写service
- 6.编写controller
- 7.运行
- 三、遇到的问题和解决过程
- 1.返回数据的自定义格式
- 2.关于@PostConstruct的使用
- 3.导出jar时注意事项
- 四、总结
- 五、参考文献和博客
SpringBoot是后端开发轻量级的框架之一,主要用于各种应用和网页的后端开发(接口编程),通过“约定大于配置”的方法简化了应用搭建和开发过程。我主要是用Springboot+mybatis来实现后端接口的开发,对于刚接触的人来说,比较难理解的就是其IOC与AOP(但实际上你只要稍微了解一下就行 )。
我来介绍一下如何快速地使用Springboot+Mybatis进行开发。
工具:IntelliJ IDEA 2022.1、MySQL 8.0、SpringBoot 2.5.2
客户端通过访问接口发出请求,然后tomcat转给我们的后端controller,controller再调用service里的业务逻辑,service再调用dao层进行一系列的处理,最后将结果返回给用户,我们在dao层使用Mybatis对数据库进行操作。
通俗的来说,整个过程有点像你在餐馆点菜,你(客户)告诉服务员(controller)你需要啥,然后服务员(controller)找后厨,然后几个厨师(service)对你的请求进行处理,他们使用不同的做菜技术(dao)对食材(data)进行处理,最后将结果给你。
- 新建项目
- 选择依赖,我们主要用到的依赖分别是SpringWeb,MySQL Driver,Lombok,Spring Boot DevTools,MyBatis Framework,JDBC API
- 数据库准备
package com.peekaboo.test.demo.entity;
import lombok.Data;
@Data
public class User {
private String id;
private String name;
private int sex;
private String password;
public User(String id, String name, int sex, String password) {
this.id = id;
this.name = name;
this.sex = sex;
this.password = password;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4.编写mapper(dao)
public interface UserMapper {
//新增用户
@Insert("INSERT into user(id,name,sex,password) VALUES(#{id},#{name},#{sex},#{password})")
int saveUser(@Param("id") String id, @Param("name") String name, @Param("sex")int sex,@Param("password") String password);
//把注册用户新增到repeat_check
@Insert("INSERT into repeat_check(id,checkID) VALUES(#{id},#{checkID})")
int savaCheckUser(@Param("id") String id, @Param("checkID") int checkID);
//根据id查询用户
@Select("select * from user where id=#{id}")
User selectUser(@Param("id") String id);
//修改个人信息
@Update("UPDATE user SET name=#{name},sex=#{sex} where id=#{id}")
int updateUser(@Param("id") String id, @Param("name") String name, @Param("sex")int sex);
//修改密码
@Update("UPDATE user SET password=#{password} where id=#{id}")
int updatePassword(@Param("id") String id,@Param("password") String password);
}
5.编写service
service层如果你业务逻辑较少,可不要,直接在controller层里写就可以了,也就相当于service层合并到controller里了
我这里直接跳过了
@RestController:将你的返回值转换成json格式
@RequestMapping:接口访问路径
@PostMapping:post请求,参数内为接口访问路径
@GetMapping:get请求,参数为接口访问路径
@Slf4j
@RequestMapping("user")
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
private static final String Md5Password = "peekabooGame";
//登录接口
@PostMapping("login")
public Result login(String id, String password) {
User user = userMapper.selectUser(id);//根据id查询用户
if (user == null) {//用户为空
return Result.error(FAIL.getCode(), "不存在该用户");
}
int resultCount= userMapper.isRepeat(id);
if (Objects.equals(Encryption(password), user.getPassword())&&resultCount==0) {//输入的密码和数据库的密码相同
int resultCheck=userMapper.updatecheckID(id,1);
return Result.success("登录成功", "");
}
return Result.error(FAIL.getCode(), "用户密码错误或账户已被使用");
}
//注册接口
@PostMapping("register")
public Result register(String id, String name, int sex, String password) {
User user = userMapper.selectUser(id);//根据id查询用户
if (user != null) {//用户为空
return Result.error(FAIL.getCode(), "用户已存在");
}
int resultCount = userMapper.saveUser(id, name, sex, Encryption(password));//增加用户
int resultCheck=userMapper.savaCheckUser(id,0);//把注册用户新增到repeat_check
if (resultCount == 0) {
return Result.error(FAIL.getCode(), "注册失败");
}
return Result.success("注册成功", "");
}
//md5加密
public String Encryption(String password) {
String md5Password = DigestUtils.md5Hex(password);
return DigestUtils.md5Hex(password + Md5Password);
}
//获取个人信息接口
@GetMapping("getUserMessage")
public Result userMessage(String id) {
User user = userMapper.selectUser(id);//根据id查询用户
Map map = new HashMap<>();
List
7.运行
ip不是localhost是因为我已经部署到服务器上了,如果是本地运行则是localhost
- 问题描述:返回的数据要求具有一定结构,code,message,data等
- 解决过程:一般接口返回的数据的格式都要为json,并且有一定的结构,而springboot在一定的程度有做到这一点,我们只需要稍微加工一下就行
简易版本
使用@RestController+Map
@GetMapping("test1")
public Map test1(){
Map x=new HashMap();
x.put("name","test");
return x;
}
高级版本
使用@RestController+自定义返回模板类
模板类
package com.peekaboo.test.demo.ResultDesign; public class Result{ private int code;//返回码 private String message;//返回信息 private T data;//返回数据 public Result() {} public Result(int code, String message) { this.code = code; this.message = message; } public static Result success(String message,T data) { Result result = new Result (); result.setCode(ResultMsgEnum.SUCCESS.getCode()); result.setMessage(message); result.setData(data); return result; } public static Result error(int code, String message) { return new Result(code, message); } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
模版枚举类
package com.peekaboo.test.demo.ResultDesign;
public enum ResultMsgEnum {
SUCCESS(200, "success"),
FAIL(400, "fail"),
AUTH_ERROR(502, "授权失败!"),
SERVER_BUSY(503, "服务器正忙,请稍后再试!"),
DATABASE_OPERATION_FAILED(504, "数据库操作失败");
private int code;
private String message;
ResultMsgEnum(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return this.code;
}
public String getMessage() {
return this.message;
}
}
使用
这里我举了一个返回列表的例子
//返回rank_list列表
@GetMapping("/getRank")
public Result getRank()
{
rankList.clear();//先清空排行榜
rankList=userMapper.selectRankAll();//重新加载排行榜列表
return Result.success("成功", rankList);
}
2.关于@PostConstruct的使用
- 问题描述:在有些时候,我们想在用户访问接口之前初始化某个变量时,我们会发现Springboot的controller里的构造函数好像没用,甚至用不了,这个时候就要使用@PostConstruct
例如下面这个例子,我想在程序运行之后就从数据库读取数据然后初始化freePort这个列表,而不是在用户访问接口后再初始化。 - 解决过程:
@Autowired
private RoomMapper roomMapper;
public static RoomController roomController;
public List rooms = new ArrayList<>();//房间列表
public List freePort = new ArrayList<>();//空闲端口列表
//初始化,从数据库中读取空闲的端口装入空闲端口列表
@PostConstruct
public void init() {
roomController = this;
roomMapper = this.roomMapper;
freePort = roomController.roomMapper.getAllFreePort("0");//获取空闲端口
}
3.导出jar时注意事项
- 问题描述:导出jar后,无法运行
- 解决过程:这个原因大概是因为你没有把Springboot所依赖的jar一起导出,一般来说导出jar文件非常的多。
总的来说,Spring Boot+Mybatis用来做后端接口开发是非常方便的工具,让我深刻体会到了面向接口编程,这种前后端分离的开发,对于整个项目来说都是非常好的,前端只要关注界面的设计和功能的设计,而后端只要关注数据处理和逻辑的处理,前后端可以并行开发。
五、参考文献和博客- 博客
1.Springboot API流程简单图示——hexter——简书
2.Spring Boot如何自定义Http的返回结果类——offmmj——CSDN
3.@PostConstruct作用——star9595——CSDN - 视频
1.新手一节课入门spring boot,手把手教你写java web和接口——耕耕技术宅——Bilibili - 文献
Java EE企业级应用开发教程——黑马程序员



