1.商品分类的展现
1.1业务描述
controller
@RequestMapping("/list")
public List<EasyUITree> dofindItemCatList(){
return itemCatService.findItemCatList();
}
@RequestMapping("/list")
public List<EasyUITree> dofindItemCatList(Long id){
Long parentId=(id==null?0L:id);
//System.out.println(itemCatService.findItemCatList(parentId));
return itemCatService.findItemCatList(parentId);
}
1.2 树形控件
树控件读取URL。子节点的加载依赖于父节点的状态。当展开一个封闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http请求参数并命名为’id’,通过URL发送到服务器上面检索子节点。
1.用户在默认条件下 如果没有展开子节点,则不会发送请求.
2.当用户打开封闭的节点时,则会将改节点的ID当做参数,向后端服务器请求.
1.3商品的CRUD
1.3.1商品的新增
1.3.2页面js
function submitForm(){
//表单校验
if(!$('#itemAddForm').form('validate')){
$.messager.alert('提示','表单还未填写完成!');
return ;
}
//转化价格单位,将元转化为分
$("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100);
itemAddEditor.sync();//将输入的内容同步到多行文本中
var paramJson = [];
$("#itemAddForm .params li").each(function(i,e){
var trs = $(e).find("tr");
var group = trs.eq(0).text();
var ps = [];
for(var i = 1;i<trs.length;i++){
var tr = trs.eq(i);
ps.push({
"k" : $.trim(tr.find("td").eq(0).find("span").text()),
"v" : $.trim(tr.find("input").val())
});
}
paramJson.push({
"group" : group,
"params": ps
});
});
paramJson = JSON.stringify(paramJson);//将对象转化为json字符串
$("#itemAddForm [name=itemParams]").val(paramJson);
/*$.post/get(url,JSON,function(data){....})
?id=1&title="天龙八部&key=value...."
*/
//alert($("#itemAddForm").serialize());
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}else{
$.messager.alert("提示","新增商品失败!");
}
});
}
eval():将包裹的字符转转化为数据
$("#itemAddForm").serialize() 表单的序列化
ajax中数据的格式两种:1.{key1:value1,key2:value2…} 2.字符串的拼接:key1=value1&key2=value2…
jQuery中表单的序列化操作 ,将表单数据以字符串的形式拼接
1.3.3提取系统的vo
不能出现包含关系的数据;json是字符串类型,如果传递字符串数据(data)会被当作string类型的msg进行方法的重载,不能满足业务需求
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@Accessors(chain=true)
@AllArgsConstructor
public class SysResult {
private Integer status;//200表示成功 201表示失败
private String msg; //服务器给用户的提示的信息
private Object data; //服务器返回给用户的数据
//封装工具API
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
@RequestMapping("/save")
public SysResult saveItem(Item item){
try{
itemService.saveItem(item);
return SysResult.success();
}catch(Exception e){
e.printStackTrace();
return SysResult.fail();
}
}
ItemServiceImpl
@Override
public void saveItem(Item item) {
Date date=new Date();
item.setStatus(1).setCreated(date).setUpdated(date);
itemMapper.insert(item);
}
增加事务控制
@Transactional //开启事务的控制
1.4参数的自动填充
需求说明:用户在入库或者更新操作时,能否实现时间的自动填充功能。简化用户操作的步骤
添加注解:
package com.jt.pojo;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.experimental.Accessors;
//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
@TableField(fill= FieldFill.INSERT)//新增操作时添加数据
private Date created;
@TableField(fill=FieldFill.INSERT_UPDATE)//新增更新操作时更新数据
private Date updated;
}
编写配置类
package com.jt.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component //交给spring容器进行管理
public class MyMetaObjectHandler implements MetaObjectHandler {
//完成入库和更新操作的自动赋值
@Override
public void insertFill(MetaObject metaObject) {
Date date=new Date();
this.setInsertFieldValByName("created",date,metaObject);
this.setInsertFieldValByName("updated",date,metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setInsertFieldValByName("updated",new Date(),metaObject);
}
}
测试自动填充功能:
1.5全局异常处理机制
1.5.1 全局异常处理机制说明
1.如果将大量的异常处理写到代码中虽然可以保证程序稳定的运行.但是代码的结构非常的混乱.
2.异常是程序运行状态的一种体现.如果没有一种统一的规则来管理异常,则程序一旦出错问题无法定位.
3.异常从哪里接受????在Controller层进行拦截(mapper—>service—>controller---->用户),接收异常
4.使用AOP中异常通知完成功能
添加jar包文件
<!--依赖的作用:依赖需要的jar包文件 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<!--spring-boot-starter-xxx springboot启动项
开箱即用:
只需要引入特定的jar包简单的配置,即可以使用该功能
-->
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--支持热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--引入插件lombok 自动的set/get/构造方法插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--添加数据库驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--springBoot整合jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--SpringBoot整合MybatisPlus mybatis和plus jar包冲突的-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!--springBoot整合JSP添加依赖 -->
<!--servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--jstl依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--使jsp页面生效 -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--添加httpClient jar包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--引入dubbo配置 -->
<!--<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>-->
<!--添加Quartz的支持 -->
<!-- <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>-->
<!-- 引入aop支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--spring整合redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
</dependencies>
编辑全局异常处理类
package com.jt.aop;
import com.jt.vo.SysResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice //aop+异常通知
public class SystemException {
//当遇到某种类型的异常时才会执行
@ExceptionHandler({RuntimeException.class})
public Object exception(Exception e){
e.printStackTrace();
//如果出错,返回系统级别的报错数据即可
return SysResult.fail();
}
}
1.6商品修改
1.6.1工具栏
<script type="text/javascript">
/*通过js创建表格 */
$(function(){
$("#table3").datagrid({
/*定义工具栏 */
toolbar: [{
iconCls: 'icon-edit',
handler: function(){alert("点击工具栏")}
},'-',{
iconCls: 'icon-help',
handler: function(){alert('帮助工具栏')}
},'-',{
iconCls: 'icon-save',
handler: function(){alert('保存工具栏')}
}],
columns:[[
{field:'itemIds',checkbox:true},
{field:'itemId',title:'商品Id',width:100},
{field:'itemName',title:'商品名称',width:100},
{field:'itemDesc',title:'商品描述',width:100,align:'right'}
]],
fitColumns:true, //自动适应
url:"datagrid_item.json", //请求数据的地址
method:"get", //提交方式
striped:true, //有条纹的行
nowrap:true, //提高加载性能
loadMsg:"正在加载", //加载数据时打印
pagination:true, //分页加载
rownumbers:true, //显示行号
//singleSelect:true, //只允许选中一行数据
})
})
</script>
UI框架提供了关于form表单操作的方式,load函数就表示数据的加载
1.6.2实现商品类目的回显
需要将3动态展现为具体名称,实现思路:获取3的id,之后发起ajax请求,在对应位置进行数据的展现
页面JS的编写
/*
实现商品分类名称的回显:
步骤:
1.获取商品分类的ID号
2.发送ajax请求
3.将返回值结果在指定位置显示
*/
let cid=data.cid;
$.get("/item/cat/queryItemName",{"itemCatId":cid},
function(data){//data代表返回的数据,name名称
$("#itemeEditForm input[name='cid']").prev("span").text(data);
})
jquery属性赋值:
1.val() 为value属性赋值
2.text() 为标签文本赋值
1.7商品的编辑操作
1.7.1实现数据的回显
1.7.2编写controller
//item 商品的修改
@RequestMapping("/update")
public SysResult doUpdateItem(Item item){
itemService.updateItem(item);
return SysResult.success();
}
itemServiceImpl
@Override
@Transactional
public void updateItem(Item item) {
itemMapper.updateById(item);
}
1.8商品的删除
itemController
@RequestMapping("/delete")
public SysResult doDeleteItemByIds(Integer[] ids){
itemService.deleteByIds(ids);
return new SysResult().success();
}
itemServiceImpl
@Override
public void deleteByIds(Integer[] ids) {
//itemMapper.deleteBatchIds(Arrays.asList(ids));
itemMapper.deleteItemByIds(ids);
}
itemMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.ItemMapper">
<!--留着以后用 -->
<delete id="deleteItemByIds">
DELETE FROM tb_item WHERE id IN
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
</mapper>
页面中 参数是如何实现传递的,底层实现是什么
用servlet中Request,Reponse对象进行参数的传递
注意事项:方法中的参数名称,必须与页面中的name属性名称一致
Mybatis参数传递的问题
知识点:Mybatis参数传递跟版本有关系
Mybatis在底层实现时是按照下标的方式取值,但是下标默认值都是0 mybatis只能传递一个参数(单值传递)如果传递一个参数,sql中参数的取值是可以任意写
需要实现多值的传递 核心思想:将多值转化为单值
长用方法:1.使用对象封装 #{对象的属性}
2.可以封装为数组/list 特殊字符array或者list
3.Map集合 #{key} 在mapper端加别名@Param注解
高版本说明:如果参数的个数多于一个时,默认采用Map的方式进行封装 若只有一个数组值会当成数组处 理,数组用array在SQL端获取
低版本说明:如果参数的个数有多个,需要手动的封装
1.9商品的上架/下架操作
1.9.1业务说明
上架操作:status1 下架操作:status2
当用户点击上架下架实现响应的上架下架操作
修改页面的请求:
编写controller
/**
* 商品状态信息的修改
* */
@RequestMapping("{status}")
public SysResult doUpdateState(@PathVariable Integer status,Integer[] ids){
itemService.updateStateByIds(status,ids);
return SysResult.success();
}
itemServiceImpl
@Override
public void updateStateByIds(Integer status,Integer[] ids) {
UpdateWrapper<Item> updateWrapper=new UpdateWrapper<>();
Item item=new Item();
item.setStatus(status);
updateWrapper.in("id", Arrays.asList(ids));
itemMapper.update(item, updateWrapper);
}
手写sql;
商品上架下架功能实现的测试: