写在前面的话:
后端接口流程
不知道各位小伙伴拿到自己的第一个实战项目的心情是如何的?是兴奋,是紧张,还是茫然? 如上所示,为此篇文章的核心思想的体现!这是“同事”+“同学”+“自己”在项目中的所思所学所得。此次的内容我将在我之前的文章SpringBoot_实现基本增删改查(前后端分离版)基础之上将自己的相关理解写得更加透彻一些,因为8月份我刚接触这个框架,很多还是混淆的状态,只知道要这样做,但是不知道为什么要这样做,这此我就来讲讲为什么要这样做。 思想归思想,思想流程是如上这样,但是具体的编码过程应当按以下的步骤来梳理,逻辑才会更加的清晰易懂!建立实体类;Service接口;XML文件;Mapper接口;ServiceImpl实现类;Controller层调用接口;最终接口展示。
建立实体类
实体类是连通着我们的前端接口内容,返回的响应参数都是来自于这儿,参数的数据类型和注释都是来源于这里,所以建立实体类作为我们刚开始编码的第一步毋庸置疑。建立的同时也能知道我们最终是要得到什么值返回给前端,这样我们后面的步骤就围绕着如何得到我们的实体类而行动。 这里想说明的是,因为很多时候返回给前端是一个集合类型,存储着很多的数据。这个时候,我们一般是建立两个实体类,一个实体类用来存储List<>集合,另外一个是用来存储该集合里的内部数据。具体的代码实例如下所示:其中,我们每个类之前加上一个“@Data”注解,能给我们省去不少的工作量。@Data注解的作用有为当前类提供读写方法,从而不用写get、set方法;为当前类提供equals()、hashCode()、toString()方法@ApiModelProperty注解:是对各个属性的说明,加上这一注解可以在Swagger中看到响应参数的相关注释内容,让前端工作者能第一时间获取到数据信息提示,提供方便。
package com.hncr.system.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @ClassName: UserVo
* @Description:用户集合实体类
* @Author: YuHao
* @Date: 2021/12/15
*/
@Data
public class UserVo {
@ApiModelProperty('用户集合')
private List userListVos;
}
package com.hncr.system.domain.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @ClassName: UserListVo
* @Description:用户类
* @Author: YuHao
* @Date: 2021/12/15
*/
@Data
public class UserListVo {
@ApiModelProperty('姓名')
private String name;
@ApiModelProperty('年龄')
private Integer age;
@ApiModelProperty('性别:(0:男,1:女)')
private Integer sex;
}
完成第一步以后,我们开始写第二个部分。所谓的基于“接口编程”思想大概就是基于Service接口进行的吧!返回类型是我们的UserVo实体类,因为最终要得到的值就是要返回一个集合给前端,所以这里的返回类型便是我们的实体类。具体的代码实例如下所示:
package com.hncr.system.service;
import com.hncr.system.domain.vo.UserVo;
/**
* @InterfaceName: IUserService
* @Description: Service接口
* @Author: YuHao
* @Date: 2021/12/15
*/
public interface IUserService {
UserVo userSummary();
}
XML文件
其实第三步和第四步是同时进行,之所以将XML文件先写,是因为我们需要将我们的sql语句写好,确定具体需要多少个sql语句才能解决具体的Service接口问题。具体问题具体分析,有时候写一个sql语句就搞定问题了,有时候也需要三四个才行。逻辑不清晰的时候建议去咨询一下前辈或者需求的同事,他们一般都能将你的疑问给解决掉。之前我也发几篇基础版的基于mysql写基本增删查改的sql语句,但是应付项目上的操作还是差点意思,因为牵扯到很多业务逻辑的时候,基本的几个就不够看了。 在Navicat中做一些实例操作:根据年龄进行降序排序
(其实在实际项目中要查询或者改变的操作会很多,数据量也会很大,很多时候要对某些个字段做索引操作才会缩短查询的时间,特别说明一下,查询时间超过3秒或者4秒的sql,在前端看来就是一个相当慢的接口了。数据量大的数据库,我们尽量做到只访问一次就好,以避免浪费不必要的时间来影响用户的体验)在Navicat工具中我们已经查询得到我们想要的效果了,那我们要加入到我们的XML文件中,结合我们的第四步配置namespace、id、resultType等。实例代码如下:
Mapper接口
其实在第三步过程中写好我们的sql语句后,就应该跳转到第四步当中了,因为具体的命名空间等是要以Mapper接口来命名的。在上面可知用一条sql语句就搞定了想要的结果,那Mapper接口写一个即可。反正就是sql写了几个,我们对应的就得写几个Mapper接口,其实例代码如下所示: 可以看到这里的返回类型不太一样了哦,因为我之前的文章中是写的List
package com.hncr.system.mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
/**
* @InterfaceName: UserService
* @Description:Mapper接口
* @Author: YuHao
* @Date: 2021/12/15
*/
@Repository
public interface UserMapper {
List userSummaryMapper();
}
到了第五步,这可以算是当前所写后端接口中至关重要的一步了,因为在这里要实现数据的交互,代码逻辑。这里分别对应着流程中的三个环节“最终值、中间值、层层计算”,如果我们通过sql语句就能得到我们想要的结果,这个结果称之为“最终值”,如果通过sql语句只是得到我们中间环节的某些值,这些值我们称之为“中间值”,需要通过我们在实现类中用相关的逻辑代码进行“层层计算”。直接能够得到最终值的是最为简单的过程,从数据库拿到数据就可以用,这个接口做起来会非常地快,因为压根就不需要用脑子呀,拿到数据直接“Set”就完事了。但是如果所做的项目相对而言逻辑复杂一点的,那么很多时候从数据库拿到的都是原始数据作为我们的中间值,这些数据是要通过我们的“通用/共用/公用方法”层层计算才能得到想要的最终值。不管如何,最终都是要Set到我们的对象之中,直接上所对应的实例代码,这样看起来直观明了:
package com.hncr.system.service.impl;
import com.hncr.system.domain.vo.UserListVo;
import com.hncr.system.domain.vo.UserVo;
import com.hncr.system.mapper.UserMapper;
import com.hncr.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName: UserServiceImpl
* @Description:
* @Author: YuHao
* @Date: 2021/12/15
*/
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
List userSummaryMapper(){
return userMapper.userSummaryMapper();
}
public UserVo userSummary(){
UserVo userVo = new UserVo();
List list1 = userSummaryMapper();
List list2 = new ArrayList<>();
for (int i = 0; i < list1.size(); i++) {
UserListVo userListVo = new UserListVo();
Map map = list1.get(i);
userListVo.setName((String) map.get('name'));
userListVo.setAge((Integer) map.get('age'));
userListVo.setSex((Integer) map.get('sex'));
list2.add(userListVo);
}
userVo.setUserListVos(list2);
return userVo;
}
}
以上的代码获取到是最终值,是直接Set到对象之中的。上面的实例代码算是最简单的了,提醒刚入门的小伙伴们,这种方式都是一些较常规做法,是需要掌握的。如果这里出来的是中间值,也不需要怕什么,所谓的“层层计算”这些什么的我们都是在大学期间或多或少接触过,我们不管是用什么语言编程都是做过的,不外乎就是“for、if、while、简单的常规算法…”,这个时候让我想到大学为啥那时候要学习数据结构了,因为不管你是码农也好还是算法工程师也罢,把这个学好都是会有用武之地的!!!
Controller层调用接口
写完前五步的内容,第六步算是结尾工作了,跟以前的做法类似,这里就是一个调用过程,将相关的注解写好,注入相关的接口方法,然后返回给前端,就完成了我们的一个接口,记住了,这才是仅仅的一个而已,还有更多其他类似或者复杂一丢丢的接口在等着你去写哦~~照惯例上我们的实例代码:
package com.hncr.web.controller.system;
import com.hncr.system.domain.JsonResult;
import com.hncr.system.domain.vo.UserVo;
import com.hncr.system.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName: UserController
* @Description:
* @Author: YuHao
* @Date: 2021/12/15
*/
@RestController
@Api(value = '用户信息', tags = '用户信息')
@RequestMapping('/user')
public class UserController {
@Autowired
private IUserService userService;
@ApiOperation(value = '用户信息汇总', notes = '{
' +
' 'msg': '操作成功',
' +
' 'code': 200,
' +
' 'data': {
' +
' }
' +
'}')
@GetMapping('UserSummary')
public JsonResult userSummary(){
UserVo userVo = userService.userSummary();
return JsonResult.success(userVo);
}
}
以上的Controller层代码中,很多我都在以前都做过介绍了,这里我就不再累赘了,就是几个非常常用的注解,不记得就多回头看看自己或者同事以前写过的项目代码,还有直接copy使用也可以。主要想说的是,本人这有一个不错的json返回值类,我也将其贴出来,大家可以拿这个用,这是已离职的好朋友分享给我的,其实他技术挺强,但是因为学历限制了他的发展,确实可惜了。这就说明了其实企业还是比较看重学历的,有一个好一点的学历,起步工资还是高不少的!!!加油吧,小伙伴们,下面是具体的代码:
package com.hncr.system.domain;
import com.alibaba.fastjson.JSONObject;
import com.hncr.common.constant.HttpStatus;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @ClassName: JsonResult
* @Description: json 返回值
* @Author: YuHao
* @Date: 2021/11/25
*/
@Data
public class JsonResult{
@ApiModelProperty(notes = '响应码')
private Integer code;
@ApiModelProperty(notes = '响应消息')
private String msg;
@ApiModelProperty(notes = '返回数据')
private T data;
/**
* 若没有数据返回,默认状态码为 0,提示信息为“操作成功!”
*/
public JsonResult() {
this.code = HttpStatus.SUCCESS;
this.msg = 'success';
}
/**
* 若没有数据返回,可以人为指定状态码和提示信息
* @param code
* @param msg
*/
public JsonResult(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 有数据返回时,状态码为 0,默认提示信息为“操作成功!”
* @param data
*/
public JsonResult(T data) {
this.data = data;
this.code = HttpStatus.SUCCESS;
this.msg = 'success';
}
public static JsonResult success(){
return new JsonResult<>();
}
public static JsonResult success(T data){
return new JsonResult(data);
}
public static JsonResult error(String msg){
return new JsonResult(HttpStatus.ERROR,msg);
}
public static JsonResult error(){
return new JsonResult(HttpStatus.ERROR,'error');
}
public static JsonResult error(int code, String msg){
return new JsonResult(code,msg);
}
public static JsonResultBuilder builder(){
return new JsonResultBuilder();
}
public static class JsonResultBuilder{
private JSONObject buildData = new JSONObject();
public JsonResultBuilder put(String key,Object value){
buildData.put(key,value);
return this;
}
public JsonResult get(){
return JsonResult.success(buildData);
}
}
}
最终接口展示
最终访问我们的本地地址+“#dohtml”,在Swagger中可以看到我们的接口已经写好了,展示的效果也是按照年龄降序排列的集合。这样的接口,前端的同事拿来就可以用,响应参数、参数数据类型都是非常的清晰。此处我是在已有的项目上做的演示实例,所以Swagger都是已经配置好的,所以此处有是瑕疵的。如果没有配置Swagger的小伙伴应该还需要先百度一下如何配置好Swagger,下个阶段我有时间也整理一下如何配置Swagger。讲实话没有Swagger看不到最终的前端调用效果确实挺难受的,所以这个环节是在我们在写接口之前就要配置好。
这便是基于SpringBoot后端接口的相关流程,有相关的思想也有编写的步骤。有些思想或者步骤我可能写得还不够细,还比较粗糙,但是大致地想法还是表达到位了。我的初衷就是想对于刚入门的小伙伴还是有一些小小的帮助的就好,自己也算是对我的第一个实战项目做大致的总结。最终项目告一段落,界面接口完成了,Bug也改了不少,新增需求也做了一些改善,后续的代码也做了一些优化。成长了不少,也收获了不少,当然也加了很多很多的班…
不管如何,大家还是要参与到实际的项目中,才会逐步收获到一些从来没有遇到过的“惊喜”!!!
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点