day 04 SpringBoot - JSON
此文档是根据上课流程编写,更多细节和图片请参见刘老师的专栏
江哥的专栏
一. 完成京淘的后台页面分析
上部,左侧,下部,右侧,中部
easy-layout.jsp
easy-tree.jsp
-
商品管理
- 商品查询
- 商品新增
-
我是三级biaoqian
- 一
- 一
- 一
-
商品管理
easy-table.jsp
二. 展现商品的列表
Item表的分析
@JsonIgnoreProperties(ignoreUnknown=true) //表示JSON转化时忽略未知属性 @TableName("tb_item") @Data @Accessors(chain=true) public class Item extends BasePojo{ @TableId(type=IdType.AUTO) private Long id; //商品id private String title; //商品标题 private String sellPoint; //商品卖点信息 private Long price; //商品价格 Long > dubbo 0.9999998+0.00000002=0.9999999 private Integer num; //商品数量 private String barcode; //条形码 private String image; //商品图片信息 1.jpg,2.jpg,3.jpg private Long cid; //表示商品的分类id private Integer status; //1正常, 2下架 //为了满足页面调用需求,添加get方法 public String[] getImages(){ return image.split(","); } }
UI列表的展现
i. easyui-6-datagrid.html
ii. JSON说明
JSON是一种简单的数据交换格式。JavaScript Object Notation,本质是一个string类型的字符串。
iii. JSON的基本数据类型
"名称/值"对的无序集合:对象 {"key1":value1, "key2":value2, ...}
"值"的有序集合:数组 [value1, vale2, ...]
值可以是双引号引起来的字符串,number,null,对象等,可以嵌套
{id:1,name:"tomcat"} [1,2,3,"打游戏","写代码"] { "id":1, "name":"张三", "hobbys":["敲代码","打游戏","喜欢"], "method":[ { "type":"火系", "name":"三昧真火" }, { "type":"水系", "name":"大海无量"} ] } {"a":{"aa":{"aaa":{"aaaa":null,"aaab":null},"aab":null},"ab":null},"b":null} [[[[[null,null],null],null],null],null]
表格数据展现
i. JSON结构
{ "total":2000, "rows":[ {"code":"A","name":"果汁","price":"20"}, {"code":"B","name":"汉堡","price":"30"}, {"code":"C","name":"鸡柳","price":"40"}, {"code":"D","name":"可乐","price":"50"}, {"code":"E","name":"薯条","price":"10"}, {"code":"F","name":"麦旋风","price":"20"}, {"code":"G","name":"套餐","price":"100"} ] }
ii. 编写EasyUITable vo对象
对象转化为JSON利用的是get方法, JSON转化为对象时用set方法
@Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class EasyUITable { private Long total; //记录总数 private List
- rows; //每页展现的记录 //1.通过对象的get方法获取属性及属性的值 public String getTitle(){ return "=== testGetTitle() ==="; } //2.JSON转化为对象时,调用set方法,为属性赋值 }
@RequestMapping("/testVO") @ResponseBody public EasyUITable testVO(){ Item item = new Item(); item.setId(1000L).setTitle("饮水机").setPrice(200L); Item item2 = new Item(); item.setId(2000L).setTitle("电冰箱").setPrice(300L); List
- rows = new ArrayList<>(); rows.add(item); rows.add(item2); return new EasyUITable(2000L,rows); }
iii. 表格页面分析
当添加了分页插件之后,当ajax解析时会自动拼接参数
iv. 编辑ItemController
/* 业务:分页查询商品信息 url: http://localhost:8091/item/query?page=1&rows=20 参数: page=1,rows=2 返回值: EasyUITable*/ @RequestMapping("/query") @ResponseBody //表示返回的数据是JSON public EasyUITable findItemByPage(int page,int rows){ return itemService.findItemByPage(page,rows); }
v. 编辑ItemService/Impl
@Override public EasyUITable findItemByPage(int page, int rows) { long total = itemMapper.selectCount(null); //1.手写分页 //SQL: SELECT * FROM tb_item LIMIT 起始位置(page-1)rows,查询条数rows int startIndex = (page-1)*rows; List
- itemList = itemMapper.findItemsByPage(startIndex,rows); }
vi. 编辑ItemMapper
@Select("SELECT * FROM tb_item " + "ORDER BY updated DESC " + "LIMIT #{startIndex},#{rows}") List
- findItemsByPage(int startIndex, int rows);
MyBatisPlus实现分页
i. 编辑ItemServiceImpl
//2.MybatisPlus分页 IPage mpPage = new Page(page,rows); QueryWrapper
- queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc("updated"); mpPage = itemMapper.selectPage(mpPage,queryWrapper ); total = mpPage.getTotal(); //获取记录总数 List
- itemList = mpPage.getRecords(); //获取查询当前页 return new EasyUITable(total,itemList);
ii. 编写配置类
@Configuration public class MyBatisPlusConfig { //将分页拦截器交给spring容器进行管理 @Bean public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
- queryWrapper = new QueryWrapper<>(); queryWrapper.orderByDesc("updated"); mpPage = itemMapper.selectPage(mpPage,queryWrapper ); total = mpPage.getTotal(); //获取记录总数 List
三. 实现商品格式化
格式化价格
i. 页面JS说明
价格 ii. 格式化代码
/** * formatter:KindEditorUtil.formatPrice(1300000,1) * 远程中心:查看common.js/43行代码,如何格式化价格?? */ // 格式化价格 formatPrice : function(val,row){ return (val/100).toFixed(2); }
- 格式化状态
i. 页面JS说明
状态
ii. 格式化代码
// 格式化商品的状态
formatItemStatus : function formatStatus(val,row){
if (val == 1){
return '正常';
} else if(val == 2){
return '下架';
} else {
return '未知';
}
}
实现商品分类回显
i. 页面JS说明
叶子类目 ii. 业务需求
当用户展现列表数据时,要求将商品类型的信息进行展现。根据cid查询商品类型信息进行展现。
iii. 编辑common.js
//格式化名称 findItemCatName : function(val,row){ var name; $.ajax({ type:"get", url:"/item/cat/queryItemName", data:{itemCatId:val}, cache:true, //缓存 async:false, //表示同步 默认的是异步的true dataType:"text",//表示返回值参数类型 success:function(data){ name = data; } }); return name; }
iv. 编辑ItemCat.java
@Data @Accessors(chain = true) @TableName("tb_item_cat") public class ItemCat extends BasePojo{ @TableId(type = IdType.AUTO) private Long id; //主键 private Long parentId; private String name; private Integer status; private Integer sortOrder; //排序号 private Boolean isParent; }
v. 编辑ItemCatController/ItemCatService/ItemCatMapper
@Mapper public interface ItemCatMapper extends BaseMapper
{ @Select("SELECT name FROM tb_item_cat WHERE id=#{cid}") String findCatNameByCid(int cid); } @Service public class ItemCatServiceImpl implements ItemCatService{ @Autowired private ItemCatMapper itemCatMapper; @Override public String findCatNameByCid(int cid) { return itemCatMapper.findCatNameByCid(cid); } }
public interface ItemCatService { String findCatNameByCid(int cid); }
@RestController @RequestMapping("/item/cat") public class ItemCatController { @Autowired private ItemCatService itemCatService; @RequestMapping("/queryItemName") public String findCatNameByCid(int itemCatId){ return itemCatService.findCatNameByCid(itemCatId); } }
vi. Ajax嵌套问题
由于页面中发起了两次ajax请求,并且这两次ajax请求是嵌套的关系。第一次获取表格数据,然后对页面进行刷新。第二次获取类目信息。默认条件下ajax请求时异步执行的,这就会导致第二次请求返回时,第一次请求已经先走过了需要数据的位置,不会将数据填充到所需要的位置。原因是页面只刷新了一次。
解决方案:如果遇到了ajax的嵌套问题,则一般将内层的ajax设置为同步的状态即可。这样在第二次请求没有返回结果时,第一次请求停下来等待。
vii. 扩展:JS中闭包概念
四. 实现商品树形结构展现
common.js的依赖问题
i. 在index.jsp中引入了其它页面
ii. 在common-js.jsp中引入common.js
商品分类业务分析
i. 分级说明
一般情况下商品分类分为三级
ii. 表结构的设计
一般适用于有父子级关系的数据,添加int parentId字段
一级商品分类 SELECT * FROM tb_item_cat WHERE parent_id=0
二级商品分类 SELECT * FROM tb_item_cat WHERE parent_id=74(一级id)
三级商品分类 SELECT * FROM tb_item_cat WHERE parent_id=75(二级id)
iii. 树形结构
[ { "id":"1", "text":"英雄联盟", "iconCls":"icon-save", "children":[ { "id":"4", "text":"沙漠死神" },{ "id":"5", "text":"德玛西亚" },{ "id":"6", "text":"诺克萨斯之手" }, { "id":"7", "text":"蛮族之王" }, { "id":"8", "text":"孙悟空" } ], "state":"open" },{ "id":"2", "text":"王者荣耀", "children":[ { "id":"10", "text":"阿科" },{ "id":"11", "text":"吕布" },{ "id":"12", "text":"陈咬金" },{ "id":"13", "text":"典韦" } ], "state":"closed" }, { "id":"3", "text":"吃鸡游戏", "iconCls":"icon-save" } ]
iv. JSON结构
[{"id":100,"text":"tomcat","state":"open/closed"},{},{}] 节点的数组
v. 编写EasyUITree vo对象
@Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor public class EasyUITree { //{"id":100,"text":"tomcat","state":"open/closed"} private Integer id; private String text; private String state; }
新增页面分析item-add.jsp
i. 页面的流转过程
1) 点击商品新增按钮;2) 发起请求 /page/item-add;3) 请求被IndexController中的restFul拦截;4) 实现页面跳转 /WEB/INF/views/item-add.jsp
ii. 页面结构分析
选择类目
iii. 编辑ItemCatController