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


    项目讲解

    具体功能如何实现

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


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

    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连接起来

    再看

    点进来

    DScq3R.md.png

    就进到了你的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时候 显示我要传递的数据

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

  • 相关阅读:
    C# 根据当前登录的用户信息,显示数据库中登录用户的照片
    C# 根据当前系统时间,显示 Good Morning/Afternoon/Evening
    C# 根据用户性别,在身份证号输入框后 面显示问候信息,格式为:“Mrs./Mr. Name”。
    C# 窗体登录,按照他们的角色跳转到不同的主界面
    C# 实现模拟下载功能,被下载的文件存储在本地
    C# 鼠标移动到图片上显示提示文字
    C# 隔一段时间自动刷新弹框(医院病人超时提醒)
    C# winform 点击窗体内不同按钮显示不同的文字
    gulp的安装和使用
    es6 面向对象
  • 原文地址:https://www.cnblogs.com/laowt/p/13983544.html
Copyright © 2020-2023  润新知