项目讲解
具体功能如何实现
以下仅仅代表本人观点(未毕业学生实习中...)
需要到的技术(纯后端开发)
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项目主要分为一下三层
- contorller
- servise
- 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注解
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
- @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
这里是一个控制权限的代码
通过后台数据库给你权限 去查询你能查询的数据
List
定义一个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 看他的Ipml 与Dao层
定义了一个这样的封装
主要是为了传递他的 信息 code 就是使用状态
List<String> dutyDepartment = UserUtils.getUserDepartment();
一个筛选工具 筛选需要的东西
回到controller
抛出一个异常 看一下能不能 把设备分类名称 传递过来 放到 JSONObiect里
这里是对应的service接口定义
这里是对应的Impl下的实现
这里是对应的工具类unitl具体代码逻辑
翻译
为了前端交互 json 的定义
在最前边 什么是json里有写
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。
翻译人能听懂的话就是 **我从后端传到前端的数据能显示出来前端需要的格式**
最后Controller
这几行代码
在本地text时候 显示我要传递的数据
一个前后交互的基本功能 基本逻辑 一般就到此了