Springboot+Mybatis接口快速上手

这个作业属于哪个课程软件工程实践2022年春-F班
这个作业要求在哪里软件工程实践总结&个人技术博客
这个作业的目标个人技术博客
其他参考文献CSDN、博客园

一、技术概述

  SpringBoot是后端开发轻量级的框架之一,主要用于各种应用和网页的后端开发(接口编程),通过“约定大于配置”的方法简化了应用搭建和开发过程。我主要是用Springboot+mybatis来实现后端接口的开发,对于刚接触的人来说,比较难理解的就是其IOC与AOP(但实际上你只要稍微了解一下就行 )。

二、技术详述

我来介绍一下如何快速地使用Springboot+Mybatis进行开发。
工具:IntelliJ IDEA 2022.1、MySQL 8.0、SpringBoot 2.5.2

1.先了解一下具体的实现原理(如果不想看可以直接跳过

在这里插入图片描述
  客户端通过访问接口发出请求,然后tomcat转给我们的后端controller,controller再调用service里的业务逻辑,service再调用dao层进行一系列的处理,最后将结果返回给用户,我们在dao层使用Mybatis对数据库进行操作。
  通俗的来说,整个过程有点像你在餐馆点菜,你(客户)告诉服务员(controller)你需要啥,然后服务员(controller)找后厨,然后几个厨师(service)对你的请求进行处理,他们使用不同的做菜技术(dao)对食材(data)进行处理,最后将结果给你。

2.准备阶段

  • 新建项目
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/14860a3f26814077bdbf9e56122f659a.png
  • 选择依赖,我们主要用到的依赖分别是SpringWeb,MySQL Driver,Lombok,Spring Boot DevTools,MyBatis Framework,JDBC API
    在这里插入图片描述
  • 数据库准备
    在这里插入图片描述
    在这里插入图片描述

3.编写实体层

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里了
我这里直接跳过了

6.编写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<String, String> map = new HashMap<>();
        List<Map<String, String>> x = new ArrayList<>();
        if (user != null) {
            map.put("id", user.getId());
            map.put("name", user.getName());
            map.put("sex", user.getSex() + "");
        } else {
            return Result.error(FAIL.getCode(), "获取信息失败");
        }
        x.add(map);
        return Result.success("获取信息成功", x);
    }

    //修改个人信息
    @PostMapping("updateUser")
    public Result updateUser(String id, String name, int sex) {
        User user = userMapper.selectUser(id);//根据id查询用户
        if (user == null) {//用户为空
            return Result.error(FAIL.getCode(), "用户不存在");
        }
        int result = userMapper.updateUser(id, name, sex);
        if (result <= 0) {
            return Result.error(FAIL.getCode(), "更新失败");
        }
        return Result.success("更新成功", "");
    }

    //修改密码
    @PostMapping("updatePassword")
    public Result updatePassword(String id, String password) {
        User user = userMapper.selectUser(id);//根据id查询用户
        if (user == null) {//用户为空
            return Result.error(FAIL.getCode(), "用户不存在");
        }
        int result = userMapper.updatePassword(id, Encryption(password));
        if (result <= 0) {
            return Result.error(FAIL.getCode(), "密码更新失败");
        }
        return Result.success("密码更新成功", "");
    }

}

7.运行

ip不是localhost是因为我已经部署到服务器上了,如果是本地运行则是localhost
在这里插入图片描述

三、遇到的问题和解决过程

1.返回数据的自定义格式

  • 问题描述:返回的数据要求具有一定结构,code,message,data等
  • 解决过程:一般接口返回的数据的格式都要为json,并且有一定的结构,而springboot在一定的程度有做到这一点,我们只需要稍微加工一下就行
    简易版本
    使用@RestController+Map
@GetMapping("test1")
    public Map<String,String> test1(){
        Map<String,String> x=new HashMap();
        x.put("name","test");
        return x;
    }

在这里插入图片描述
高级版本
使用@RestController+自定义返回模板类
模板类

package com.peekaboo.test.demo.ResultDesign;

public class Result<T> {
    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 <T> Result<T> success(String message,T data) {
        Result<T> result = new Result<T>();
        result.setCode(ResultMsgEnum.SUCCESS.getCode());
        result.setMessage(message);
        result.setData(data);
        return result;
    }
    /**
     * 失败
     */
    public static <T> Result<T> 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<Room> rooms = new ArrayList<>();//房间列表
    public List<Port> 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
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值