項目講解
具體功能如何實現
以下僅僅代表本人觀點(未畢業學生實習中...)
需要到的技術(純后端開發)
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時候 顯示我要傳遞的數據
一個前后交互的基本功能 基本邏輯 一般就到此了