具体功能如何实现

以下仅仅代表本人观点(未毕业学生实习中...)


需要到的技术(纯后端开发)

json+spring boot+mybatis puls+mysql数据库

面向接口编程

解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的实现 , 大家都遵守共同的标准 , 使得开发变得容易 , 规范性更好

在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不那么重要了;

而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。


关于接口

接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。

接口的本身反映了系统设计人员对系统的抽象理解。

接口应有两类:

第一类是对一个个体的抽象,它可对应为一个抽象体(abstract class);

第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);

一个体有可能有多个抽象面。抽象体与抽象面是有区别的。


什么是json:

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。

翻译人能听懂的话就是 我从后端传到前端的数据能显示出来前端需要的格式


什么是spring boot:

从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用。

翻译成人能听懂的话就是spring boot 就是一个框架

特点: 自动装配控制反转


什么是Mybatis:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

翻译成人能听懂的话就是Mybatis就是一个高级的JDBC

在翻译就是java语言怎么和数据库连接

这就是Mybatis!


什么是mysql数据库:

不想说...


一个java web项目主要分为一下三层

如何进行后端开发 (大体逻辑)

  1. contorller
  2. servise
  3. dao

流程图:

如何进行后端开发 (大体逻辑)


controller层

  • 最重要的一点就是提供api接口与前端交互

以下是我截取的片段代码(controller层)具体的一个前端交互实现

@Api(tags = "设备台账-设备列表")
@RestController
@RequestMapping("/ledger")
@Slf4j
public class LedgerController {
@Autowired
private ApparatusInfoService apparatusInfoService;

@Autowired
private SysDdictionariesService sysDdictionariesService;

@Autowired
private ApparatusProcessService apparatusProcessService;

@Autowired
private ApparatusStatsService apparatusStatsService;
@SysLog("创建设备")
@ApiOperation("创建")
@PostMapping("/apparatus")
@RequiresPermissions("ledger:apparatusinfo:save")
public R create(@RequestBody ApparatusInfoDTO apparatusInfoDTO) {
    String categoryName = apparatusInfoDTO.getCategoryName();
    if (StringUtils.isEmpty(categoryName) ||
            StringUtils.isEmpty(apparatusInfoDTO.getSn()) ||
            StringUtils.isEmpty(apparatusInfoDTO.getUsestate())) {
        log.error("faield to ledger create, 必要参数为空");
        return R.ok("创建失败,请填写完整信息");
    }
    boolean b = apparatusInfoService.createCheckSn(apparatusInfoDTO.getSn());
    if (!b) {
        log.error("faield to ledger create, 设备编码已存在");
        return R.error("设备编码已存在");
    }
    JSONObject infoTemplate = null;
    String statsInfo = null;
    try {
        statsInfo = JsonUtils.getStrToJson(categoryName, "realtime");
    } catch (Exception e) {
        log.error("faield to ledger create statsInfo", e);
        return R.error("创建失败");
    }
    ApparatusStatsEntity status = new ApparatusStatsEntity();

    String infoString = apparatusInfoDTO.getInfoString();
    if (StringUtils.isEmpty(infoString)) {
        try {
            infoTemplate = apparatusInfoService.getInfoTemplate(categoryName, "static");

            apparatusInfoDTO.setInfo(infoTemplate);
        } catch (Exception e) {
            log.error("faield to ledger create infoTemplate", e);
            return R.error("创建失败");
        }
    } else {
        JSONObject info = JSONObject.parseObject(infoString);
        apparatusInfoDTO.setInfo(info);
    }
    SysUserEntity user = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
    apparatusInfoDTO.setCreatetime(new Date());
    JSONObject statusTemplate = (JSONObject) JSONObject.parse(statsInfo);
    apparatusInfoDTO.setStatusthreshold(statusTemplate);
    apparatusInfoDTO.setCreateuser(user.getUsername());
    ApparatusInfoEntity apparatusInfo = ApparatusInfoDTO.getInfoEntity(apparatusInfoDTO);
    try {
        apparatusInfoService.save(apparatusInfo);
        Long infoid = apparatusInfoService.selectInfoid(apparatusInfoDTO.getSn());
        status.setInfoid(infoid);
        status.setInfo(statsInfo);
        status.setCreatetime(new Date());
        status.setCreateuser(user.getUsername());
        apparatusStatsService.createStatus(status);
        log.info("ledger create, infoEntity:{}, apparatusInfoDTO:{}", apparatusInfo, apparatusInfoDTO);
        return R.ok("创建成功");
    } catch (Exception e) {
        log.error("faield to ledger create createStatus", e);
        return R.error("创建失败");
     }
   }
}

//Class R 返回状态码与信息
public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;

public R() {
	put("code", 0);
	put("msg", "success");
}

public static R error() {
	return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}

public static R error(String msg) {
	return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}

public static R error(int code, String msg) {
	R r = new R();
	r.put("code", code);
	r.put("msg", msg);
	return r;
}

public static R ok(String msg) {
	R r = new R();
	r.put("msg", msg);
	return r;
}

public static R ok(Map<String, Object> map) {
	R r = new R();
	r.putAll(map);
	return r;
}

public static R ok() {
	return new R();
}

public R put(String key, Object value) {
	super.put(key, value);
	return this;
}

}

如何进行后端开发 (大体逻辑)

程序开头 有这4个注解

注解:spring 4.0特性 帮助开发

分析一下这4个注解

@Api(tags = "设备台账-设备列表")这是个swagerr注解
表示标识这个类是swagger的资源

如何进行后端开发 (大体逻辑)

@RestController

@RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

翻译一下就是 后台返回数据用这个


@RequestMapping(/ledger)

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

就是相当于返回映射到这个url下 http://localhost :8080/xxx/ledger


@Slf4j

log的注解 打印日志到哪里的注解 (java代码规范有写:log可以设定级别,可以控制输出到哪里,容易区分是在代码的什么地方打印的,而System.out.print则不行。而且,System.out.print的速度很慢。所以,除非是有意的,否则,都要用log。至少在提交到svn之前把System.out.print换成log。--来源gittab)


再往下看代码


如何进行后端开发 (大体逻辑)

@Autowired

@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法

翻译一下就是 把你的Controller与service连接起来

再看

如何进行后端开发 (大体逻辑)

点进来

如何进行后端开发 (大体逻辑)

就进到了你的Service
extends继承
IService<> 一个方法
ApparatusStatsEntity 这个是其他类中的class代码具体就是把数据库有的字段定义出来

Entity中具体代码

package cn.galaiot.modules.ledger.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
	* @author zhangtong
	* @date 2020-09-04 14:06:29
 */
@Data  //注解 有了这个就不需要get set方法了
@TableName(value = "apparatus_process", autoResultMap = true)
public class ApparatusProcessEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
     * 主键id
 */
@TableId
private Long id;
/**
     * 设备id
 */
private Long infoid;
/**
 * 操作时间
 */
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date operationtime;
/**
 * 管理内容
 */
private String managecontent;
/**
 * 实施方式
 */
private String implement;
/**
 * 实施方
 */
private String executor;
/**
 * 费用
 */
private Double expense;
;
/**
 * 完好待用时间
 */
private Long readyforusetime;
/**
 * 运转时间
 */
private Long runningtime;
/**
 * 故障时间
 */
private Long faulttime;
/**
 *正常保养时间
 */
private Long normalmaintenancetime;
/**
 * 维保时间
 */
private String maintenancetime;
/**
 * 备注
 */
private String remark;
/**
 * 值班人
 */
private String inspector;
/**
 * 开始维保时间
 */
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date starttime;
/**
 * 维保结束时间
 */
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date endtime;
/**
 * 责任人
 */
private String responsible;
/**
 * 任务描述
 */
private String description;
/**
 * 配套设备
 */
private String equipment;
/**
 * 详细信息
 */
@TableField(typeHandler = FastjsonTypeHandler.class)
private String info;
/**
 * 创建时间
 */
private Date createtime;
/**
 * 创建人
 */
private String createuser;
/**
 * 修改时间
 */
private Date updatetime;
/**
 * 修改人
 */
private String updateuser;
/**
 * 设备状态, -1表示删除, 0表示正常
 */
private Integer status;
}

暂且不谈Entity包是个什么东西


继续上面代码
如何进行后端开发 (大体逻辑)

又是4个注解

@SysLog
与上面 @Slf4j对应 写出log打印到哪里

@ApiOperation
首先@ApiOperation注解不是Spring自带的,它是是swagger里的
注解@ApiOperation是用来构建Api文档的
@ApiOperation(value = “接口说明”, httpMethod = “接口请求方式”, response =
“接口返回参数类型”, notes = “接口发布说明”;其他参数可参考源码;

提到swagger不得不提到RESTful风格

RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。

一个@ApiOperation的通用写法 下面是举例

@ApiOperation(value="创建用户", notes="根据User对象创建用户")
@ApiImplicitParam(name = "user", value = "用户详细实体user", required = true, dataType = "User")
@RequestMapping(value="", method=RequestMethod.POST)
public String postUser(@RequestBody User user) {
    users.put(user.getId(), user);
    return "success";
}

下一个的@PostMapping注解

  1. @PostMapping
  2. @PutMapping
  3. @DeleteMapping
  4. @PatchMapping
  5. @GetMapping

为什么这么写:

@PostMapping("/apparatus")

如何进行后端开发 (大体逻辑)

这里的和Swagger上显示的一样就行

什么是@PostMapping:

映射一个POST请求 处理post请求

等价于@RequestMapping(value = "/user/login",method = RequestMethod.POST)

Spring官方文档说:

@GetMapping是一个组合注解,是@RequestMapping(method = RequestMethod.GET)的缩写。该注解将HTTP Get 映射到 特定的处理方法上。

@PostMapping 是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写。该注解将HTTP Post 映射到 特定的处理方法上。


到public R create(@RequestBody ApparatusInfoDTO apparatusInfoDTO)

@ResponseBody:表示该方法的返回结果直接写入HTTP response body中,一般在异步获取数据时使用,用于构建RESTful的api。在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。

比如异步获取json数据,加上@responsebody后,会直接返回json数据。该注解一般会配合@RequestMapping一起使用。


点击ApparatusInfoDTO 跳转到public class ApparatusInfoDTO extends ApparatusInfoEntity


写到这里可以缓一缓了 不要急来到service层

至于为什么 就因为这个程序里的第一行代码~

HashMap<String, Object> date = apparatusInfoService.getAll(params);
分析代码
HashMap<String,Object> date 定义一个hashmap集合 名字为 date
apparatusInfoService.getAll(params)
apparatusInfoService.得到所有 参数

这就是重点了 因为apparatusInfoService在这!

如何进行后端开发 (大体逻辑)

这里实现了Controller层交互service层。

service层

如何进行后端开发 (大体逻辑)

service下有两个

一个叫做xxxxService

另一个叫xxxxServiceImpl

Service 是接口

Impl 是实现


xxxService 代码

public interface ApparatusInfoService extends IService<ApparatusInfoEntity> {
//获取所有数据列表,支持条件搜索和分页
HashMap<String,Object> getAll(Map<String, Object> params);
}

如何进行后端开发 (大体逻辑)

上面是controller里的代码

下面是service里的代码

注意是怎么连接在一起的 命名与取名

当你在这里写好一个接口以后你的同级目录下的xxxImpl就会报错

因为实现可以没有方法 但一定要实现


xxxserviceImpl 代码

@Service("apparatusInfoService")
public class ApparatusInfoServiceImpl extends ServiceImpl<ApparatusInfoDao, ApparatusInfoEntity> implements ApparatusInfoService {
@Resource
private ApparatusInfoDao apparatusInfoDao;
 public HashMap<String, Object> getAll(Map<String, Object> params) {
    HashMap<String, Object> date = new HashMap<>();
    List categorys = null;
    List useStates = null;
    List departments = null;
    String likeKey = StringUtils.defaultIfEmpty((String) params.get("likeKey"), "name");
    String likeValue = (String) params.get("likeValue");
    likeValue = "%" + likeValue + "%";
    //分页参数
    Long curPage = 0L;
    Long limit = 10L;
    if (params.get(Constant.PAGE) != null) {
        curPage = Long.parseLong((String) params.get(Constant.PAGE)) - 1L;
    }
    if (params.get(Constant.LIMIT) != null) {
        limit = Long.parseLong((String) params.get(Constant.LIMIT));
    }
    Long start = curPage * limit;
    String json = (String) params.get("preciseValue");
    if (!StringUtils.isEmpty(json)) {
        HashMap<String, String> map = JSON.parseObject(json, HashMap.class);
        Set<String> keys = map.keySet();
        for (String key : keys) {
            switch (key) {
                case "category":
                    String categorysString = map.get(key);
                    if (StringUtils.isEmpty(categorysString)) {
                        break;
                    }
                    categorys = Arrays.asList(categorysString.split(","));
                    break;
                case "usestate":
                    String useStatesString = map.get(key);
                    if (StringUtils.isEmpty(useStatesString)) {
                        break;
                    }
                    useStates = Arrays.asList(useStatesString.split(","));
                    break;
                case "department":
                    String departmentsString = map.get(key);
                    if (StringUtils.isEmpty(departmentsString)) {
                        break;
                    }
                    departments = Arrays.asList(departmentsString.split(","));
                    break;
            }
        }
    }
    List<String> unit = UserUtils.getUserDepartment();
    List<ApparatusInfoEntity> apparatusInfos = apparatusInfoDao.getAllByKey(likeKey, likeValue, start, limit, categorys, useStates, departments, unit);
    Long count = apparatusInfoDao.getCount(likeKey, likeValue, categorys, useStates, departments, unit);
    date.put("apparatusInfos", apparatusInfos);
    date.put("num", count);
    return date;
 }
}

代码分析!

注解:@service :一般用于修饰service层的组件

翻译:连接service与controller

注解:@Resource :这个注解属于J2EE,默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

翻译:不用写setter方法,减少了与spring的耦合

private ApparatusInfoDao apparatusInfoDao;

直观的就是用在了这行代码

要注意同样的代码在不同的层如和耦合在一起的

如何进行后端开发 (大体逻辑)

继续分析Impl代码 我把实现的第一代码整个copy

如何进行后端开发 (大体逻辑)

前几个List定义一些数组

	List categorys = null;
    List useStates = null;
    List departments = null;
    List newname=null;

这里使用了unitl类 实现了一个分页功能

	String likeKey = StringUtils.defaultIfEmpty((String) params.get("likeKey"), "name");
    String likeValue = (String) params.get("likeValue");
    likeValue = "%" + likeValue + "%";
    //分页参数
    Long curPage = 0L;
    Long limit = 10L;
    if (params.get(Constant.PAGE) != null) {
        curPage = Long.parseLong((String) params.get(Constant.PAGE)) - 1L;
    }
    if (params.get(Constant.LIMIT) != null) {
        limit = Long.parseLong((String) params.get(Constant.LIMIT));
    }
    Long start = curPage * limit;
    String json = (String) params.get("preciseValue");

代码分析!

String likeKey = StringUtils.defaultIfEmpty((String) params.get("likeKey"), "name");
//String likeKey =跳转了一个Utils类.跳转到defaultIfEmpty里实现isEmpty(str) ? defaultStr : str这个 params.get("这个是在dao层里一会看")

StringUtils 跳转了一个Utils类

//Utils类功能
public class StringUtils {
public static final String EMPTY = "";
public static final int INDEX_NOT_FOUND = -1;
private static final int PAD_LIMIT = 8192;

public StringUtils() {
}

public static boolean isEmpty(String str) {
    return str == null || str.length() == 0;
}

public static boolean isNotEmpty(String str) {
    return !isEmpty(str);
}

public static boolean isBlank(String str) {
    int strLen;
    if (str != null && (strLen = str.length()) != 0) {
        for(int i = 0; i < strLen; ++i) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }

        return true;
    } else {
        return true;
    }
}

public static String defaultIfEmpty(String str, String defaultStr) {
    return isEmpty(str) ? defaultStr : str;
}

当前源代码的下一行代码

String likeValue = (String) params.get("likeValue");
传过来的在dao层里的参数 ^likeValue^

Dao层

dao层叫数据访问层,全称为data access object,属于一种比较底层,比较基础的操作,具体到对于某个表、某个实体的增删改查

dao层代码

@Mapper
public interface ApparatusInfoDao extends BaseMapper<ApparatusInfoEntity> {
String fileds = "id, category, sn, assetSn, assetClassifySn, assetCategorySn, " +
        " sn5, model, underWarranty, useState, status, name, department, manufacturers," +
        " factorySn, factoryTime, factoryTime, commissioningTime, workTime, maintainenceTime, " +
        " faultTime, initRunTime, currentRunTime, pesponsible, dutyDepartment, position, power" +
        ", info, statusThreshold, remark, principal, createTime, createUser, updateTime, updateUser";
String tableName = "apparatus_info";

@Select("<script> " +
        "select " + fileds + " from " + tableName + " " +
        "<where> " +
        "status = 0  " +
        "and department in " +
        "<foreach item='units' index='index' collection='unit' open='(' separator=',' close=')'> " +
        "#{units} " +
        "</foreach> " +
        "<if test=' likeValue != null and likeValue != \"\" '> " +
        "and ${likeKey} like #{likeValue}" +
        "</if> " +
        "<if test=' categorys != null and categorys.size > 0 '> " +
        "and category in " +
        "<foreach item='category' index='index' collection='categorys' open='(' separator=',' close=')'> " +
        "#{category} " +
        "</foreach> " +
        "</if> " +
        "<if test=' useStates != null and useStates.size > 0 '> " +
        "and useState in " +
        "<foreach item='useState' index='index' collection='useStates' open='(' separator=',' close=')'> " +
        "#{useState}" +
        "</foreach>" +
        "</if> " +
        "<if test=' departments != null and departments.size > 0 '> " +
        "and department in " +
        "<foreach item='department' index='index' collection='departments' open='(' separator=',' close=')'> " +
        "#{department} " +
        "</foreach> " +
        "</if> " +
        "</where>" +
        "limit #{start}, #{limit} " +
        "</script> ")
List<ApparatusInfoEntity> getAllByKey(@Param("likeKey") String likeKey,
                                      @Param("likeValue") String likeValue,
                                      @Param("start") Long start,
                                      @Param("limit") Long limit,
                                      @Param("categorys") List<String> categorys,
                                      @Param("useStates") List<String> useStates,
                                      @Param("departments") List<String> departments,
                                      @Param("unit") List<String> unit);

Dao层代码解析

@Mapper注解的的作用:

1:为了把mapper这个DAO交給Spring管理 

2:为了不再写mapper映射文件 

3:为了给mapper接口 自动根据一个添加@Mapper注解的接口生成一个实现类	

String fileds = "id, category, sn, assetSn, assetClassifySn, assetCategorySn, " +
        " sn5, model, underWarranty, useState, status, name, department, manufacturers," +
        " factorySn, factoryTime, factoryTime, commissioningTime, workTime, maintainenceTime, " +
        " faultTime, initRunTime, currentRunTime, pesponsible, dutyDepartment, position, power" +
        ", info, statusThreshold, remark, principal, createTime, createUser, updateTime, updateUser";
String tableName = "apparatus_info";

String fileds=“xxx”;这行代码就是对数据库表里的字段进行定义 因为Mybatis的sql语句最好不要写*号

如何进行后端开发 (大体逻辑)

String tableName =“xxx” 这就是相对应的表名

如何进行后端开发 (大体逻辑)

@Select

Mybatis的注解 字面意思 查询

Mybatis 像是一个xml语言

@Select("<script> " +
        "select " + fileds + " from " + tableName + " " +
        "<where> " +
        "status = 0  " +
        "and department in " +
        "<foreach item='units' index='index' collection='unit' open='(' separator=',' close=')'> " +
        "#{units} " +
        "</foreach> " +
        "<if test=' likeValue != null and likeValue != \"\" '> " +
        "and ${likeKey} like #{likeValue}" +
        "</if> " +
        "<if test=' categorys != null and categorys.size > 0 '> " +
        "and category in " +
        "<foreach item='category' index='index' collection='categorys' open='(' separator=',' close=')'> " +
        "#{category} " +
        "</foreach> " +
        "</if> " +
        "<if test=' useStates != null and useStates.size > 0 '> " +
        "and useState in " +
        "<foreach item='useState' index='index' collection='useStates' open='(' separator=',' close=')'> " +
        "#{useState}" +
        "</foreach>" +
        "</if> " +
        "<if test=' departments != null and departments.size > 0 '> " +
        "and department in " +
        "<foreach item='department' index='index' collection='departments' open='(' separator=',' close=')'> " +
        "#{department} " +
        "</foreach> " +
        "</if> " +
        "</where>" +
        "limit #{start}, #{limit} " +
        "</script> ")

代码拆分

"select " + fileds + " from " + tableName + " " +
    "<where> " +
    "status = 0  " +
    "and department in " +
    "<foreach item='units' index='index' collection='unit' open='(' separator=',' close=')'> " +
    "#{units} " +
	"</foreach> " 

select 字段 from 表名 where status=0 和 department

按照 status 和 地点 查询 存入 #{units}

"<foreach item='units' index='index' collection='unit' open='(' separator=',' close=')'> " +
		"#{units} " +
	"</foreach>

foreach 就是脚本中循环

就是把 循环的把 status 和 地点 查询结果 存入 #{units}

Mybatis 中的特性

代码拆分

"<if test=' likeValue != null and likeValue != \"\" '> " +
    "and ${likeKey} like #{likeValue}" +
    "</if> " +
    "<if test=' categorys != null and categorys.size > 0 '> " +
    "and category in " +
    "<foreach item='category' index='index' collection='categorys' open='(' separator=',' close=')'> " +
    "#{category} " +

${likeKey} like #{likeValue}
模糊查询 与dao层对应

要看这行代码的话需要回到 impl

如何进行后端开发 (大体逻辑)

<if test=' categorys != null and categorys.size > 0 '> 

这行有基础都可以看得懂吧

后三行

	"and category in " +
    "<foreach item='category' index='index' collection='categorys' open='(' separator=',' close=')'> " +
    "#{category} " +

这三行

和前几行一样
就是把category字段下的数据 循环的存入 #{category} 里

中间代码这些都差不多

具体不讲了

最后

"limit #{start}, #{limit} " 

把limt 存入一个Start 又存入一个Limit


如何进行后端开发 (大体逻辑)

先说注解

@Param

@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应

传回参数到 后边定义得 字符串 或者集合 最后在传入getAllByKey集合里


可以回到Impl

如何进行后端开发 (大体逻辑)

代码分析

这这些代码就是为了实现一个分页功能


HashMap<String, String> map = JSON.parseObject(json, HashMap.class);

JSON.parseObject

JSON JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串

翻译就是 后端传过去得 在前端能显示出来


impl下的后续代码

如何进行后端开发 (大体逻辑)

List unit=UserUtils.getUserDepartment();

这里是一个控制权限的代码

如何进行后端开发 (大体逻辑)

通过后台数据库给你权限 去查询你能查询的数据

如何进行后端开发 (大体逻辑)

如何进行后端开发 (大体逻辑)


List apparatusInfos = apparatusInfoDao.getAllByKey(likeKey, likeValue, start, limit, categorys, useStates, departments, unit);

定义一个apparatusInfos集合
用来存放 后端传过来的

这是Dao层的代码传到impl里likeKey, likeValue, start, limit, categorys, useStates, departments, unit 参数

如何进行后端开发 (大体逻辑)

配合前面一个控制until 实现查询的权限

继续分析前面的代码

如何进行后端开发 (大体逻辑)

看到Long count=xxxDao.getCount();

进入getCount 以下是他的Dao层代码

		@Select("<script> " +
        "select count(id) from " + tableName + " " +
        "<where> " +
        "status = 0  " +
        "and department in" +
        "<foreach item='units' index='index' collection='unit' open='(' separator=',' close=')'> " +
        "#{units} " +
        "</foreach> " +
        "<if test=' likeValue != null and likeValue != \"\" '> " +
        "and ${likeKey} like #{likeValue}" +
        "</if> " +
        "<if test=' categorys != null and categorys.size > 0 '> " +
        "and category in " +
        "<foreach item='category' index='index' collection='categorys' open='(' separator=',' close=')'> " +
        "#{category} " +
        "</foreach> " +
        "</if> " +
        "<if test=' useStates != null and useStates.size > 0 '> " +
        "and useState in " +
        "<foreach item='useState' index='index' collection='useStates' open='(' separator=',' close=')'> " +
        "#{useState}" +
        "</foreach>" +
        "</if> " +
        "<if test=' departments != null and departments.size > 0 '> " +
        "and department in " +
        "<foreach item='department' index='index' collection='departments' open='(' separator=',' close=')'> " +
        "#{department} " +
        "</foreach> " +
        "</if> " +
        "</where>" +
        "</script> ")
Long getCount(@Param("likeKey") String likeKey,
              @Param("likeValue") String likeValue,
              @Param("categorys") List<String> categorys,
              @Param("useStates") List<String> useStates,
              @Param("departments") List<String> departments,
              @Param("unit") List<String> unit);

前面讲过了 具体不讲了

这几行代码呢 就是把后端传过来的数据进行分页 分页之后进行显示

把所有的数据呢返回到date集合里


Dao层与Impl层 讲解完毕 回到Controller层

如何进行后端开发 (大体逻辑)

public R list(@RequestParam HashMap<String, Object> params)

先说一下这个public R list

R:

public class R extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;

public R() {
	/**
	 * 下面是常见的HTTP状态码:
	 * 200 - 请求成功
	 * 301 - 资源(网页等)被永久转移到其它URL
	 * 404 - 请求的资源(网页等)不存在
	 * 500 - 内部服务器错误
	 *
	 * 可以参考这样的设计 错误归类  +++9/【·方便寻找
	 * #1000~1999 区间表示参数错误
	 * #2000~2999 区间表示用户错误信息
	 * #3000~3999区间表示接口异常
	 * */
	put("code", 0);//返回一个code状态码

	put("msg", "success");
}

public static R error() {
	return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}

public static R error(String msg) {
	return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}

public static R error(int code, String msg) {
	R r = new R();
	r.put("code", code);
	r.put("msg", msg);
	return r;
}

public static R ok(String msg) {
	R r = new R();
	r.put("msg", msg);
	return r;
}

public static R ok(Map<String, Object> map) {
	R r = new R();
	r.putAll(map);
	return r;
}

public static R ok() {
	return new R();
}

public R put(String key, Object value) {
	super.put(key, value);
	return this;
	}
}

这个就是 前后交互 后端传归来一个状态值 和信息 必须得有!

附上一个讲解较为详细的文档

https://www.jianshu.com/p/fa75acba5b07
		转自简述作者 码不动

@RequestParam:将请求参数绑定到你控制器的方法参数上

HashMap<String, Object> date = apparatusInfoService.getAll(params);

这行代码就是在Service层中定义的接口getAll得到所有参数

Long num = (Long) date.get("num");

定义一个长整型 num 得到num里的参数

List<ApparatusInfoEntity> apparatusInfos = (List<ApparatusInfoEntity>) date.get("apparatusInfos");

这行就是得到apparatusInfos这个参数的所有信息 放到一个新集合里

List<String> useState = sysDdictionariesService.selectNameByKeyWord("使用状态");

这行有定义了一个新接口 后期运行时候发现少定义的实现状态 重新定义的
进入到他的Service 看他的IpmlDao

定义了一个这样的封装

如何进行后端开发 (大体逻辑)

主要是为了传递他的 信息 code 就是使用状态


List<String> dutyDepartment = UserUtils.getUserDepartment();

如何进行后端开发 (大体逻辑)

一个筛选工具 筛选需要的东西


回到controller

如何进行后端开发 (大体逻辑)

抛出一个异常 看一下能不能 把设备分类名称 传递过来 放到 JSONObiect

这里是对应的service接口定义
如何进行后端开发 (大体逻辑)

这里是对应的Impl下的实现

如何进行后端开发 (大体逻辑)

这里是对应的工具类unitl具体代码逻辑

如何进行后端开发 (大体逻辑)

翻译

为了前端交互 json 的定义
在最前边 什么是json里有写

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。


翻译人能听懂的话就是 **我从后端传到前端的数据能显示出来前端需要的格式**

最后Controller
这几行代码

如何进行后端开发 (大体逻辑)

在本地text时候 显示我要传递的数据

一个前后交互的基本功能 基本逻辑 一般就到此了

相关文章:

  • 2022-12-23
  • 2022-01-02
  • 2021-08-16
  • 2022-12-23
  • 2021-12-09
  • 2021-07-31
  • 2021-05-05
  • 2021-11-27
猜你喜欢
  • 2022-12-23
  • 2021-08-16
  • 2022-01-14
  • 2022-12-23
  • 2022-12-23
  • 2021-08-25
  • 2021-08-06
相关资源
相似解决方案