@Service
public class ItemServiceImpl implements ItemService {
@Autowired
private ItemMapper itemMapper;
/**
*编辑代码技巧: 记忆部分关键字,之后根据方法提示,完成任务.
* 说明:利用MP的方式实现分页操作
*
*/
@Override
public EasyUITable findItemByPage(Integer current, Integer size) {
//1.定义Page 简单分页对象
Page<Item> page = new Page<>(current, size);
//2.按照updated 降序排列
OrderItem orderItem = new OrderItem();
orderItem.setColumn("updated")
.setAsc(false);
page.addOrder(orderItem);
//3.执行分页查询操作
IPage<Item> iPage = itemMapper.selectPage(page,null);
//4.封装返回值 long-->int
return new EasyUITable((int)iPage.getTotal(), iPage.getRecords());
}
}
package com.jt.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
@Configuration //标识我是一个配置类 早期通过xml配置文件的方式进行整合,SpringBoot之后用配置类代替xml
public class MPConfig {
//如果需要使用MP的分页机制.则需要配置分页插件即可
//将分页插件交给Spring容器管理
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
说明: 叶子类目其实就是商品的分类信息.要求根据商品分类ID信息,查询商品分类的名称
说明:在jt-common的pojo包中添加ItemCat对象.
//该POJO对象是商品分类信息
@TableName("tb_item_cat") //标识对象与表关系
@Data
@Accessors(chain=true)
//@NoArgsConstructor
//@AllArgsConstructor
public class ItemCat extends BasePojo{
@TableId(type=IdType.AUTO)
private Long id; //主键标识
private Long parentId; //定义父级分类id
private String name; //商品分类名称
private Integer status; //商品分类状态
private Integer sortOrder; //商品分类排序号
private Boolean isParent; //是否为父级.
}
package com.jt.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jt.pojo.ItemCat;
import com.jt.service.ItemCatService;
import com.jt.service.ItemService;
//一般要求返回的数据都是JSON
@RestController
@RequestMapping("/item/cat")
public class ItemCatController {
//编码规范: 1.POJO 2.mapper 3.service 4.controller
@Autowired
private ItemCatService itemCatService;
/**
* 1. 业务需求: 根据商品分类ID值965,其实需要根据965的ID的值查询商品分类名称. 发起ajax请求获取商品名称.
2. 页面url请求地址: http://localhost:8091/item/cat/queryItemName
3. url请求参数: itemCatId: 965
4. 返回值结果: 要求返回商品分类的名称
*/
@RequestMapping("/queryItemName")
public String findItemCatNameById(Long itemCatId) {
//1.根据id查询商品分类对象信息
ItemCat itemCat = itemCatService.findItemCatById(itemCatId);
//2.从对象中获取name属性
return itemCat.getName();
}
}
package com.jt.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.ItemCat;
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private ItemCatMapper itemCatMapper;
//根据Id查询商品分类信息
@Override
public ItemCat findItemCatById(Long itemCatId) {
return itemCatMapper.selectById(itemCatId);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EasyUI-3-菜单按钮</title>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css"
href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<link rel="stylesheet" type="text/css"
href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<script type="text/javascript">
//让页面加载完成
$(function(){
//1.利用jQuery动态获取input中的参数
//步骤: 1.利用选择器选中数据 2.利用函数获取数据
//1.选择器的类型 1.id选择器 #号 2.元素选择器 标签信息 3.类选择器 .
var value = $("#input1").val(); //根据元素,获取里边的值
//alert(value);
//2.修改input中的数据
$("#input1").val("我是修改后的数据"); //准确的定位元素信息
var num = $("input").length; //获取标签的个数
//alert("input标签一共有:"+num);
//3.类选择器
var value2 = $(".myClass").val();
//alert("通过class选择器获取数据:"+value2);
//为btn1添加点击事件,function(){点击完成之后,程序执行的动作}
$("#btn1").bind("click",function(){
//.windows效果是JS插件EasyUI工具动态提供的.
$("#win1").window({
title:"弹出框",
width:400,
height:400,
modal:false //这是一个模式窗口,只能点击弹出框,不允许点击别处
})
})
$("#btn3").click(function(){
alert("关闭");
$("#win2").window("close");
});
/*定义退出消息框 */
$("#btn4").click(function(){
//消息提示框架
$.messager.confirm('abc','你确定要退出吗',function(r){
if (r){
alert("确认退出");
} else{
alert("哦! 原来你点错了!!! 下次手不要欠!!!!!")
}
});
})
/*定义消息提示框 */
$.messager.show({
title:'My Title',
msg:'郑哥你都胖成一个球了,圆的',
timeout:5000,
height:200,
width:300,
showType:'slide'
});
})
</script>
</head>
<body>
用户姓名: <input class="myClass" type="text" id="input1" name="input1" value="我是input标签,文本内容"/>
<h1>Easy-弹出窗口</h1>
<!--主要展现弹出框 -->
<a id="btn1" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add'">搜索</a>
<div id="win1"></div>
<!--定义弹出窗口 -->
<div id="win2" class="easyui-window" title="My Window" style="width:600px;height:400px" data-options="iconCls:'icon-save',modal:true">
我是一个窗口
<a id="btn3" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-back'">关闭</a>
</div>
<div style="float: right">
<a id="btn4" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-cancel'">退出系统</a>
</div>
</body>
</html>
说明:商品分类信息,包含父子级关系. 一般的商品分类结构分为3级菜单
2).EasyUI中树形结构展现
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EasyUI-3-菜单按钮</title>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript"
src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css"
href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<link rel="stylesheet" type="text/css"
href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<script type="text/javascript">
/*通过js创建树形结构 */
$(function(){
//.tree EasyUI中提供的函数
$("#tree").tree({
url:"tree.json", //加载远程JSON数据
method:"get", //请求方式 get/post
animate:false, //表示显示折叠端口动画效果
checkbox:true, //表述复选框
lines:true, //表示显示连接线
dnd:true, //是否拖拽
onClick:function(node){ //添加点击事件
alert("用户点击了节点")
//控制台
console.info(node);
}
});
})
</script>
</head>
<body>
<h1>EasyUI-树形结构</h1>
<ul id="tree"></ul>
</body>
</html>
3).EasyUI中树形结构的JSON规则
说明:根据树形结构的规范 如果需要展现树形结构,格式如下
[{"id":"节点编号" ,"text":"节点名称","state":"closed/open"}]
结论:如果需要展现树形结构,则需要配置三个属性 分别为id/text/state属性.
如果需要展现样式,则必须按照特定的规则编辑.
说明:按照格式要求,封装树形结构返回值VO对象
package com.jt.vo;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
//树形结构的格式要求.
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
public class EasyUITree {
private Long id;
private String text; //文本信息
private String state; //节点状态 open/closed
}
业务说明: 当用户点击商品分类按钮时,会进行弹出框操作.并且在弹出框中以树形结构的形式,展现商品分类信息.
url地址: http://localhost:8091/item/cat/list
参数: 初始化时没有参数,但是当展现子节点时,会传递id.
返回值: 返回list集合对象
详细说明:
1). 利用树形结构展现的是商品分类信息.但是树形结构要求返回的数据是EasyUITree VO对象.但是数据库中只有itemCat数据库对象信息.
2).发现返回值VO与数据库对象信息不一致,则需要程序员手动的实现对象数据的转化.
3).用户默认的条件下,只展现一级商品分类信息, 当用户点击某个一级商品分类信息时,才会展现具体的二级商品分类信息.
4).如果成功展现了1级商品分类信息,当通过一级展现二级信息时,会传递当前一级信息的ID.当作参数,发往服务器获取数据.
说明:商品分类信息,包含3级分类,通过1级查询二级信息.同理通过2级id查询3级的信息.
/*一级*/
SELECT * FROM tb_item_cat WHERE parent_id = 0
/*二级*/
SELECT * FROM tb_item_cat WHERE parent_id = 558
/*三级*/
SELECT * FROM tb_item_cat WHERE parent_id = 559
/**
* url:http://localhost:8091/item/cat/list
* 参数: 当展现二三级信息时,会传递父级的Id信息,如果展现1级菜单,则应该设定默认值
* 返回值: List
*/
@RequestMapping("list")
public List<EasyUITree> findItemCatList
(@RequestParam(name="id",defaultValue="0")Long parentId){
//1.查询一级商品分类信息,所以
return itemCatService.findItemCatList(parentId);
}
//目的为了简化代码的耦合性.每个方法都应该完成自己独立的任务
public List<ItemCat> findItemCatListByParentId(Long parentId){
QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<ItemCat>();
queryWrapper.eq("parent_id", parentId);
return itemCatMapper.selectList(queryWrapper);
}
@Override
public List<EasyUITree> findItemCatList(Long parentId) {
//1.先获取所有的一级商品分类信息.
List<ItemCat> itemCatList = findItemCatListByParentId(parentId);
//2.将CartList转化为VOlist
List<EasyUITree> treeList = new ArrayList<>(itemCatList.size());
for (ItemCat itemCat : itemCatList) {
Long id = itemCat.getId();
String text = itemCat.getName();
//如果是父级则默认关闭,如果是子级则默认打开.
String state = itemCat.getIsParent()?"closed":"open";
EasyUITree easyUITree = new EasyUITree(id, text, state);
treeList.add(easyUITree);
}
return treeList;
}
树控件读取URL。子节点的加载依赖于父节点的状态。当展开一个封闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http请求参数并命名为’id’,通过URL发送到服务器上面检索子节点。
/*
ajax中的参数提交一般分为2种形式:
1.json格式 {"id":"1","name":"tomcat猫"}
2.参数拼接 id=1&name="tomcat猫"
jQuery专门专对form表单提交指定的函数.serialize(),
作用:将整个form表单提交时,进行参数的拼接.
*/
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
//当程序执行成功之后,要执行回调函数.
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}else{
$.messager.alert("提示","新增商品失败!");
}
});
说明:在做业务操作时,定义系统级别的VO对象,当用户完成CURD操作之后.需要返回系统变量.
要素说明:
1.告知用户是否操作正确 判断依据
2.返回系统的提示信息
3.利用公共API封装服务器返回值数据
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult {
private Integer status; //200 表示成功 201表示失败.
private String msg; //服务器返回客户端消息
private Object data; //服务器返回客户端数据
public static SysResult fail() {
return new SysResult(201,"业务执行失败", null);
}
public static SysResult success() {
return new SysResult(200,"业务执行成功", null);
}
public static SysResult success(Object data) {
return new SysResult(200,"业务执行成功", data);
}
public static SysResult success(String msg,Object data) {
return new SysResult(200, msg, data);
}
}
说明:编辑itemController实现商品新增操作
/**
* url地址: http://localhost:8091/item/save
* 参数: 整合form表单提交 item对象接收参数
* 返回值: 系统返回值 SysResult对象
*/
@RequestMapping("/save")
public SysResult saveItem(Item item) {
itemService.saveItem(item);
return SysResult.success(); //用户入库成功!!!!
}
说明:编辑itemService实现商品新增操作
@Override
@Transactional //控制数据库事务 sql插入数据库 代码报错了!! 同时成功/失败
public void saveItem(Item item) {
item.setCreated(new Date())
.setUpdated(item.getCreated()); //保证用户入库时间一致
itemMapper.insert(item);
}
说明: 程序执行过程中,可能会出现异常报错信息.如果在代码中频繁的使用try-catch这样的结构则必然导致代码的结构混乱.所以需要全局异常的处理机制.
原理说明: 全局异常处理机制,是Spring利用AOP(面向切面编程)技术,利用了异常通知,实现该功能.
说明:由于异常处理机制的维护是全局的,所有代码应该写到jt-common中.
//1.标识该类是一个全局异常处理机制
@RestControllerAdvice //通知
public class SystemExcAOP {
//该异常处理机制,只对controller抛出的异常有效.
//爸爸(亿万富翁) ----自己(富二代)--------儿子(富三代) 亿解决
//只有程序抛出运行时异常时,才会被全局异常处理机制捕获.
//专业的开发人员:职业操守 自己必须处理的异常称之为检查异常.
//如果自己不想处理,则将检查异常转化为运行时异常即可.
@ExceptionHandler(RuntimeException.class)
public SysResult systeResult() {
return SysResult.fail();
}
}
1.重新完成 商品列表展现 /商品分类信息回显/商品分类树形结构展现. 必做内容
2.预习 商品修改/删除/上架/下架操作