Guns框架学习记录-1

Guns框架学习记录-1

1.基本框架搭建

1.1 mp的代码生成器
1.2 guns的代码生成器
1.3 对当前角色进行授权操作

mp的代码生成器:mybatis-plus代码生成器,主要用于生成dao、model、mapper。详情请查看http://mp.baomidou.com/#/generate-code

// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir("D:\\workspace\\guns\\guns-admin\\src\\main\\java");//这里写你自己的java目录
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert() {
    // 自定义数据库表字段类型转换【可选】
    @Override
    public DbColumnType processTypeConvert(String fieldType) {
        return super.processTypeConvert(fieldType);
    }
});
dsc.setDriverName("com.mysql.jdbc.Driver");//数据库驱动
dsc.setUsername("root");//数据库用户名
dsc.setPassword("1234");//数据库密码
dsc.setUrl("jdbc:mysql://127.0.0.1:3306/guns?characterEncoding=utf8");
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
//strategy.setTablePrefix(new String[]{"_"});// 此处可以修改为您的表前缀
strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
//重点:配置要对那张表进行生成代码操作
strategy.setInclude(new String[]{"my_order"});
mpg.setStrategy(strategy);

guns代码生成器:guns框架自带的代码生成器,用于生成controller、service + impl、js、前端html模板。详情请查看:https://gitee.com/naan1993/guns

当前admin用户启动项目后,新添加菜单:订单管理(一级)以及添加订单、修改订单、编辑订单三个二级菜单。将admin用户获得订单管理所有权限。

这里需要注意:生成的二级菜单的请求地址一定要和guns代码生成器生成的order.html中请求一致。原因是:

guns代码生成器生成的html模板中含有shiro权限管理的页面标签,所以应该给当前用户授权,否则看不到页面中的按钮。
@if(shiro.hasPermission("/order/add")){
    <#button name="添加" icon="fa-plus" clickFun="Order.openAddOrder()"/>
@}
@if(shiro.hasPermission("/order/update")){
    <#button name="修改" icon="fa-plus" clickFun="Order.openOrderDetail()" space="true"/>
@}
@if(shiro.hasPermission("/order/delete")){
    <#button name="删除" icon="fa-plus" clickFun="Order.delete()" space="true"/>
@}

2.简单Demo-订单管理的CURD

2.1 数据表建立
2.2 采用代码生成器生成项目骨架
2.3 实现订单管理的CURD

建立数据表:my_order

CREATE TABLE `my_order` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键id' ,
    `user` varchar(255) DEFAULT NULL COMMENT '下单人名称' ,
    `place` varchar(255) DEFAULT NULL COMMENT '地点' ,
    `goods` varchar(255) DEFAULT NULL COMMENT '商品名称' ,
    `createtime` datetime DEFAULT NULL COMMENT '下单时间' ,
    PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET = utf8;

通过代码生成器生成的代码结构为:

//mabatis-plus代码生成器
--dao 
    --mapping
        MyOrderMapper.xml   //映射文件 
    MyOrderMapper.java      //接口文件 
    --model
    MyOrder.java            //pojo类  

//guns代码生成器
--order
    --controller
        OrderController.java    //控制层代码 
    --service
        OrderService.java       //业务层接口代码
        -impl
            OrderServiceImpl.java   //业务层实现类代码
--static
    --order.order
        order.js                //业务展示
        order_info.js           //业务提交
--WEB_INF
    --order.order
        order.html              //业务展示页面模板
        order_add.html          //添加业务页面模板
        order_edit.html         //编辑业务页面模板

订单管理的CURD(详细介绍开发过程)

订单展示

1.坐标:order.js
前端页面展示订单基本信息,基本信息展示页面存放于order.html中,页面初始化逻辑存储在order.js中。我们需要对其内容改造。
需要注意:filed一定要对应数据库中表的字段名称!!!id字段由于数据库自增长,这里无需显示出来。

/**
 * 初始化表格的列
*/
Order.initColumn = function () {
    return [
        {field: 'selectItem', radio: true},
        {title: 'id', field: 'id', visible: false, align: 'center', valign: 'middle'},
        /*
        * title:需要显示的字段标题
        * field:对应数据库字段名
        * visible:字段是否可见
        * */
        {title: '下单人名称', field: 'user', visible: true, align: 'center', valign: 'middle'},
        {title: '地点', field: 'place', visible: true, align: 'center', valign: 'middle'},
        {title: '商品名称', field: 'goods', visible: true, align: 'center', valign: 'middle'},
        {title: '下单时间', field: 'createtime', visible: true, align: 'center', valign: 'middle'},
    ];
};

2.坐标:OrderController.java
表格展示已经写好,我们需要完成业务逻辑,让数据库中的订单数据展示到前台页面上。

//注入service层订单接口
@Autowired
private MyOrderMapper myOrderMapper;

/**
 * 获取订单业务列表
 */
@RequestMapping(value = "/list")
@ResponseBody
public Object list(String condition) {
    //采用工具类对字符串搜索条件进行判空处理 -- 条件商品名称
    if (ToolUtil.isNotEmpty(condition)) {
        //采用mp的条件构造器:EntityWrapper 填充like查询条件 -- 注意要使用 like %x%
        EntityWrapper<MyOrder> myOrderEntityWrapper = new EntityWrapper<>();
        myOrderEntityWrapper.like("goods",condition);
        //将构造好的条件添加入查询,执行查询
        List<MyOrder> myOrders = myOrderMapper.selectList(myOrderEntityWrapper);
        return myOrders;
    } else {
        List<MyOrder> myOrders = myOrderMapper.selectList(null);
        return myOrders;
    }
}

注意:H+ 前端模板的使用,js初始化页面的配置,mp中条件构造器EntityWrapper的使用。

添加订单

1.操作流程:用户点击'添加'按钮,添加订单页面弹出,页面上包括需要用户填写的订单的基本信息,填写完成后,点击提交即可添加成功。
这里的添加、修改均采用的请求方式分两步:点击按钮时 + 提交表单时。如:/order_add  +  /order/add 
坐标:OrderController.java

/**
 * 跳转到添加订单业务 -- 点击按钮时
 */
@RequestMapping("/order_add")
public String orderAdd() {
    return PREFIX + "order_add.html";
}

/**
 * 新增订单业务 -- 提交表单时
 */
@RequestMapping(value = "/add")
@ResponseBody
public Object add(MyOrder myOrder) {
    //添加对象判空处理 -- id自增无需设置,这里的order对象不可能为空 -- 前端已经通过js进行判断
    if (null != myOrder) {
        //补充设置下单时间字段
        myOrder.setCreatetime(new Date());
    }
    //执行插入记录操作
    Integer insert = myOrderMapper.insert(myOrder);
    return super.SUCCESS_TIP;
}

遇到的问题:空表单可以添加成功,这是逻辑不允许的,我们需要在表单中添加判空验证。

扫描二维码关注公众号,回复: 2528488 查看本文章
2.修改order_info.js,加入表单提交时的判空验证。
坐标:order_info.js

/**
* 初始化订单业务详情对话框
*/
var OrderInfoDlg = {
    orderInfoData : {},
    //添加表单空输入提示 -- 对应input框
    validateFields: {
        user: {
            validators: {
                notEmpty: {
                    message: '用户名称不能为空'
                }
            }
        },
        place: {
            validators: {
                notEmpty: {
                    message: '地点不能为空'
                }
            }
        },
        goods: {
            validators: {
                notEmpty: {
                    message: '商品名称不能为空'
                }
            }
        }
    }
};

/*
* 初始化方法中加入表单验证  
*/
$(function() {
    Feng.initValidator("orderInfoForm", OrderInfoDlg.validateFields);
});

/*
* 验证数据是否为空
* */
OrderInfoDlg.validate = function () {
    $('#orderInfoForm').data("bootstrapValidator").resetForm();
    $('#orderInfoForm').bootstrapValidator('validate');
    return $("#orderInfoForm").data('bootstrapValidator').isValid();
}

//最后在提交添加的方法中加入以下判断,目的是在点击提交时,判断是否进行了表单判空验证。
if (!this.validate()) {
    return;
}

3.对订单添加表单命名id,因为js中对id进行了表单绑定。
坐标:order_add.html
<div class="form-horizontal" id="orderInfoForm">

修改订单

1.操作流程:用户选定一条订单信息后,点击'修改'按钮后,弹出订单修改的二级页面,表单形式,包含了用户需要修改的订单基本信息。用户修改后,点击提交即可修改成功。
这里的逻辑可以分成两部分:
    根据选定订单进行订单查询展示  -- 查询
    对选定订单进行修改提交       -- 更新
上文中已经提到了添加和修改操作都分两步进行处理的,这里的修改便是:/order_update + /order/update

/**
 * 跳转到修改订单业务 -- 点击按钮时
 */
@RequestMapping("/order_update/{orderId}")
public String orderUpdate(@PathVariable Integer orderId, Model model) {
    if (ToolUtil.isEmpty(orderId)) {
        throw new BussinessException(BizExceptionEnum.REQUEST_NULL);
    }
    //根据从请求中获取的orderId进行查询
    MyOrder order = myOrderMapper.selectById(orderId);
    //将查询到的对象设置到页面中
    model.addAttribute("order", order);
    return PREFIX + "order_edit.html";
}

2.配置order_edit.html页面接受order对象,并进行展示。
<div class="row">
    <div class="col-sm-6 b-r">
        <#input id="user" name="用户名称" value="${order.user}" underline="true"/>
        <#input id="place" name="地点" value="${order.place}" underline="true"/>
    </div>

    <div class="col-sm-6">
        <#input id="goods" name="商品名称" value="${order.goods}" underline="true"/>
    </div>
</div>

3.展示订单修改页面后,用户更改订单相应数据后点击提交按钮。请求/order/update,这里有一个springmvc的对象验证问题,稍后总结。
/**
 * 修改订单业务 -- 点击提交时
 */
@RequestMapping(value = "/update")
@ResponseBody
public Object update(@Validated MyOrder order) {
    //System.out.println(order.toString());
    if (ToolUtil.isNotEmpty(order)){
        myOrderMapper.updateById(order);
    }
    return super.SUCCESS_TIP;
}   

4.当我们提交修改后的表单时候,我们也希望用户置空的字段是无法进行提交成功的。因此在order_info.js文件中添加表单置空验证。
坐标:order_info.js
if (!this.validate()) {
    return;
}

订单删除

1.操作流程:用户选定订单信息后,点击删除按钮即可删除选定的订单数据。
坐标:OrderController.java
/**
 * 删除订单业务
 */
@RequestMapping(value = "/delete")
@ResponseBody
public Object delete(@RequestParam("orderId") Integer orderId) {
    Integer deleteOrderId = myOrderMapper.deleteById(orderId);
    return SUCCESS_TIP;
}

总结问题

1.代码生成器的基本使用
2.mp中BaseMapper的学习,封装了基本的CURD操作。
3.mp中的EntityWrapper条件构造器的使用。
4.关于请求路径中参数的获取。
    @RequestParam("param"):data域中获取参数,参数要对应。
    @PathVariable("param"):url中获取参数,参数也要对应。
5.@Validated和@Valid区别。
    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303规范),javax提供了@Valid(标准JSR-303规范),配合BindingResult可以直接提供参数验证结果。
限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
举例说明:
@Valid:package=javax.validation.Valid 不提供分组校验功能。

//首先需要在实体类的相应字段上添加用于充当校验条件的注解
@NotBlank(message = "角色名不能为空")
private String rolename;

//在controller层的方法的要校验的参数上添加@Valid注解,并且需要传入BindingResult对象,用于获取校验失败情况下的反馈信息。
@RequestMapping("/add")
@ResponseBody
public Role addRole(@Valid Role role, BindingResult bindingResult) {
    //如果校验失败,打印反馈信息
    if (bindingResult.hasErrors()) {
        //打印相应属性上添加的message内容
        System.out.println(bindingResult.getFieldError().getDefaultMessage());  
        return null;  
    }
    return roleMapper.addRole(role);
}

@Validated:package=javax.validation 是对@Valid的一次封装,提供分组校验功能。
当一个实体类需要多种验证方式的时候,可以通过groups进行验证条件的分组。

定义分组接口类:
public interface Valid1() {
    //...
}
public interface Valid2() {
    //...
}
实体类属性:
    1. 不分配groups,默认每次都要进行验证。
    2. 对一个实体类参数需要多种验证方式的时候可以进行不同分组。
@NotBlank(message = "角色名不能为空", groups = {Valid1.class})
@Size(min = 3,max = 8, message = "长度不符合要求", groups = {Valid2.class})
private String rolename;

@NotNull(message = "年龄不能为空")
private int age;
控制层:
    1. @Validated中没有添加groups属性时候(@validated Role role),所有已分组的实体属性将不会进行验证。
    2. @Validated中添加groups属性时候(@validated({Group.class}) Role role),会对已分组的实体属性进行验证。
    3. 关于组排序问题:默认情况下,不同组别的约束验证是无序的,但是在某些情况下,约束验证的顺序却很重要。
        例:rolename属性,只有先进行判空验证后,才会长度的校验。这两个校验注解分别属于不同的组别,所以应该统一管理,并进行组排序。
        //采用@GroupSequence注解进行组排序和组管理。
        @GroupSequence({Valid1.class, Valid2.class})  
        public interface Group {  
            //...
        }
        此时,上一条中的@validated({Group.class}) Role role的意义就清晰了。
@RequestMapping("/add")
@ResponseBody
public Role addRole(@validated Role role, BindingResult bindingResult) {
    //如果校验失败,打印反馈信息
    if (bindingResult.hasErrors()) {
        //打印相应属性上添加的message内容
        System.out.println(bindingResult.getFieldError().getDefaultMessage());  
        return null;  
    }
    return roleMapper.addRole(role);
}
提示:@NotNull、@NotEmpty和@NotBlank区别
@NotEmpty 用在集合类上面
@NotBlank 用在String上面
@NotNull  用在基本类型上面

8/2/2018 7:20:38 PM

猜你喜欢

转载自blog.csdn.net/Nerver_77/article/details/81382552
今日推荐