业务形容

基于Spring,MyBatis,SpringBoot,Thymeleaf技术实现购物券的增删改查操作。

我的项目环境初始化

筹备工作

1. MySQL(5.7)2. JDK (1.8)3. Maven (3.6.3)4. IDEA(2020.2)

数据库初始化

关上mysql控制台,而后按如下步骤执行dbretail.sql文件。
第一步:登录mysql。

mysql –uroot –proot

第二步:设置控制台编码方式。

set names utf8;

第三步:执行dbretail.sql文件(切记不要关上文件复制到mysql客户端运行)。

source d:/dbretail.sql

其中dbvoucher.sql文件内容如下:

drop database if exists dbretail;create database dbretail default character set utf8;use dbretail;CREATE TABLE tb_voucher(     `id`  INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '主键',     `deno` DECIMAL(10,2) UNSIGNED NOT NULL COMMENT '面值',     `requirement` DECIMAL(10,2) UNSIGNED NOT NULL COMMENT '订单多少钱能够应用',     `startTime`  DATETIME  COMMENT '起始日期',     `endTime`  DATETIME  COMMENT '截至日期',     `maxNum` INT COMMENT '代金卷发放最大数量',     `remark` varchar(200) COMMENT '备注',    `createdTime`  DATETIME  COMMENT '创立日期') COMMENT='购物券表';insert into tb_voucher values (null,100,1000,'2020/05/07','2020/06/07',200,'Remark',now());insert into tb_voucher values (null,80,800,'2020/05/07','2020/06/07',300,'Remark',now());insert into tb_voucher values (null,50,500,'2020/05/07','2020/06/07',400,'Remark',now());insert into tb_voucher values (null,30,300,'2020/05/07','2020/06/07',500,'Remark',now());insert into tb_voucher values (null,10,100,'2020/05/07','2020/06/07',600,'Remark',now());

创立我的项目并增加依赖

基于IDEA创立

第一步:创立Empty我的项目并设置根本信息(如果Empty我的项目曾经存在则无需创立)

第二步:基于start.spring.io 创立我的项目Module,并设置根本信息。

第三步:创立我的项目module时指定我的项目外围依赖

第四步:持续实现module的创立并剖析其构造

我的项目配置文件内容初始化

#serverserver.port=80#spring datasourcespring.datasource.url=jdbc:mysql:///dbvoucher?serverTimezone=GMT%2B8&characterEncoding=utf8spring.datasource.username=rootspring.datasource.password=root#spring mybatismybatis.mapper-locations=classpath:/mapper/*/*.xml#spring logginglogging.level.com.cy.retail=debug

我的项目API架构设计

其API架构设计,如图所示:

商品查问业务实现

业务形容

从数据库查问购物卷信息,并将购物卷信息出现在页面上,如图所示:

业务时序剖析

查问所有购物券信息,其业务时序剖析,如图所示:

Pojo类定义

定义Voucher对象,用于封装从数据库查问到的购物券信息。

package com.cy.retail.voucher.pojo;import com.fasterxml.jackson.annotation.JsonFormat;import java.io.Serializable;import java.util.Date;/**购物卷*/public class Voucher implements Serializable {    private static final long serialVersionUID = -8863293149012534747L;    private Integer id;    /**面值*/ private Integer deno;    /**条件(多少钱能够应用)*/ private Integer requirement;    /**起始工夫*/ @JsonFormat(pattern = "yyyy/MM/dd HH:mm")    private Date startTime;    /**完结工夫*/ @JsonFormat(pattern = "yyyy/MM/dd HH:mm")    private Date endTime;    /**代金卷发放最大数量*/ private Integer maxNum;    /**备注*/ private String remark;    /**创立工夫*/ private Date createdTime;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public Integer getDeno() {        return deno;    }    public void setDeno(Integer deno) {        this.deno = deno;    }    public Integer getRequirement() {        return requirement;    }    public void setRequirement(Integer requirement) {        this.requirement = requirement;    }    public Date getStartTime() {        return startTime;    }    public void setStartTime(Date startTime) {        this.startTime = startTime;    }    public Date getEndTime() {        return endTime;    }    public void setEndTime(Date endTime) {        this.endTime = endTime;    }    public Integer getMaxNum() {        return maxNum;    }    public void setMaxNum(Integer maxNum) {        this.maxNum = maxNum;    }    public String getRemark() {        return remark;    }    public void setRemark(String remark) {        this.remark = remark;    }    public Date getCreatedTime() {        return createdTime;    }    public void setCreatedTime(Date createdTime) {        this.createdTime = createdTime;    }    @Override public String toString() {        return "Voucher{" +                "id=" + id +                ", deno=" + deno +                ", requirement=" + requirement +                ", startTime=" + startTime +                ", endTime=" + endTime +                ", maxNum=" + maxNum +                ", remark='" + remark + ''' +                ", createdTime=" + createdTime +                '}';    }}

Dao接口办法及映射定义

在GoodsDao接口中定义商品查询方法以及SQL映射,基于此办法及SQL映射获取所有商品信息。代码如下:

package com.cy.retail.voucher.dao;import com.cy.retail.voucher.pojo.Voucher;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Select;import java.util.List;@Mapperpublic interface VoucherDao {    @Select("select count(*) from tb_voucher")    int getRowCount();    @Select("select * from tb_voucher order by createdTime desc limit #{startIndex},#{pageSize}")    List<Voucher> findPageObjects(Integer startIndex, Integer pageSize);}

编写单元测试类进行测试剖析:

package com.cy.retail.voucher.dao;import com.cy.retail.voucher.pojo.Voucher;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTestpublic class VoucherDaoTests {    @Autowired    private VoucherDao voucherDao;    @Test    void testGetRowCount(){        int rowCount=voucherDao.getRowCount();        System.out.println("rowCount="+rowCount);    }    @Test    void testFindPageObjects(){        List<Voucher> list=voucherDao.findPageObjects(0,3);        list.forEach(item-> System.out.println(item));    }}

Service接口办法定义及实现

VoucherService接口及查询方法定义

package com.cy.retail.voucher.service;import com.cy.retail.common.pojo.PageObject;import com.cy.retail.voucher.pojo.Voucher;public interface VoucherService {    /** * 分页查问Voucher信息 * @param pageCurrent * @param pageSize * @return */ PageObject<Voucher> findPageObjects(Integer pageCurrent,Integer pageSize);}

VoucherService接口实现类VoucherServiceImpl定义及办法实现

package com.cy.retail.voucher.service.impl;import com.cy.retail.common.pojo.PageObject;import com.cy.retail.voucher.dao.VoucherDao;import com.cy.retail.voucher.pojo.Voucher;import com.cy.retail.voucher.service.VoucherService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class VoucherServiceImpl implements VoucherService {    @Autowired private VoucherDao voucherDao;    @Override public int deleteById(Integer id) {        return voucherDao.deleteById(id);    }    @Override public PageObject<Voucher> findPageObjects(Integer pageCurrent, Integer pageSize) {        int rowCount=voucherDao.getRowCount();        int startIndex=(pageCurrent-1)*pageSize;        List<Voucher> records=voucherDao.findPageObjects(startIndex,pageSize);        return new PageObject<>(rowCount,records,pageCurrent,pageSize);    }}

编写单元测试类进行测试剖析

package com.cy.retail.voucher.service;import com.cy.retail.common.pojo.PageObject;import com.cy.retail.voucher.dao.VoucherDao;import com.cy.retail.voucher.pojo.Voucher;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTestpublic class VoucherServiceTests {    @Autowired private VoucherService voucherService;    @Test void testFindPageObjects(){        PageObject<Voucher> pageObject=        voucherService.findPageObjects(1,3);        System.out.println(pageObject);    }}

Controller对象办法定义及实现

定义VoucherController类,并增加doFindPageObjects办法,代码如下:

ackage com.cy.retail.voucher.controller;import com.cy.retail.common.pojo.PageObject;import com.cy.retail.common.pojo.ResponseResult;import com.cy.retail.voucher.service.VoucherService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.DeleteMapping;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class VoucherController {    @Autowired private VoucherService voucherService;    @GetMapping("/voucher/doFindPageObjects/{pageCurrent}/{pageSize}")    public ResponseResult doFindPageObjects(@PathVariable Integer pageCurrent,@PathVariable Integer pageSize){        return new ResponseResult(voucherService.findPageObjects(pageCurrent,pageSize));    }}

Voucher页面设计及实现

在static目录中增加voucher.html页面,代码如下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title>    <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet"></head><body><div id="app" class="container">    <h1>The Voucher Page</h1>       <table class="table">         <thead>          <tr>            <th>序号</th>            <th>面值</th>            <th>可用条件</th>            <th>起始日期</th>            <th>截止日期</th>            <th>数量</th>            <th>操作</th>         </tr>        </thead>           <tbody>           <tr v-for="(v,i) of vouchers" :key="i">                <td>{{i+1}}</td>                <td>{{v.deno}}</td>               <td>{{v.requirement}}</td>               <td>{{v.startTime}}</td>               <td>{{v.endTime}}</td>               <td>{{v.maxNum}}</td>               <td><button class="btn btn-danger btn-xs">delete</button></td>           </tr>        </tbody>    </table>    <div id="pageId" class="box-footer clearfix" dm="100">        <ul class="pagination pagination-sm no-margin pull-right">            <li><a class="first" @click="doJumpToPage">首页</a></li>            <li><a class="pre" @click="doJumpToPage">上一页</a></li>            <li><a class="next" @click="doJumpToPage">下一页</a></li>            <li><a class="last" @click="doJumpToPage">尾页</a></li>            <li><a class="rowCount">总记录数({{rowCount}})</a></li>            <li><a class="pageCount">总页数({{pageCount}})</a></li>            <li><a class="pageCurrent">当前页({{pageCurrent}})</a></li>        </ul>    </div></div><script src="/js/axios.min.js"></script><script src="/js/vue.js"></script><script>    var vm=new Vue({        el:"#app",        data:{          vouchers:{},          pageCurrent:1,          pageCount:0,          rowCount:0 },        methods:{           doFindPageObjects(){               let url=`voucher/doFindPageObjects/${this.pageCurrent}/3`;               axios.get(url).then(function(result){                   let respData=result.data.data;                   this.vm.vouchers=respData.records;                   this.vm.rowCount=respData.rowCount;                   this.vm.pageCount=respData.pageCount;                   this.vm.pageCurrent=respData.pageCurrent;               })           },           doJumpToPage(event){               let cls=event.target.getAttribute("class");               if(cls=="first"){                   this.pageCurrent=1;               }else if(cls=="pre"&& this.pageCurrent>1){                   this.pageCurrent--;               }else if(cls=="next"&& this.pageCurrent< this.pageCount){                   this.pageCurrent++;               }else if(cls=="last"){                   this.pageCurrent= this.pageCount;               }else{                   return;               }               //3.基于新的页码值从新执行查问 this.doFindPageObjects();           }        },        mounted:function(){             this.doFindPageObjects();        }    });</script></body></html>

启动服务器进行拜访测试剖析

首先,启动tomcat,而后在关上浏览器,在地址栏输出拜访地址,获取服务端数据并进行出现,如图所示:

购物券删除业务实现

业务形容

从数据库查问购物券信息后,点击页面上删除按钮,基于id删除以后行记录,如图所示:

业务时序剖析

在购物券出现页面,用户执行删除操作,其删除时序如图所示:

Dao接口办法及映射定义

在VoucherDao接口中定义删除办法以及SQL映射,代码如下:

 @Delete("delete from tb_voucher where id=#{id}") int deleteById(Integer id);

Service接口办法定义及实现

在VoucherService接口中增加删除办法,代码如下:

int deleteById(Integer id);

在VoucherService的实现类VoucherServiceImpl中增加deleteById办法实现。代码如下。

@Override    public int deleteById(Integer id) {        int rows=voucherDao.deleteById(id);        return rows;    }

Controller对象办法定义及实现

在VoucherController中的增加doDeleteById办法,代码如下:

 @DeleteMapping("/voucher/doDeleteById/{id}")public ResponseResult doDeleteById(@PathVariable Integer id){    voucherService.deleteById(id);    return new ResponseResult(id);}

阐明:Restful 格调为一种软件架构编码格调,定义了一种url的格局,其url语法为/a/b/{c}/{d},在这样的语法结构中{}为一个变量表达式。如果咱们心愿在办法参数中获取rest url中变量表达式的值,能够应用@PathVariable注解对参数进行形容。

Voucher页面上删除按钮事件处理

在voucher.html页面中增加删除事件,代码如下:

<button @click="doDeleteById(v.id)" class="btn btn-danger btn-xs">delete</button>

在vue的methods对象中增加删除办法,代码如下:

doDeleteById(id){    let url=`voucher/doDeleteById/${id}`;    axios.delete(url).then(function(result){        alert(result.data.message);        this.vm.doFindPageObjects();    })}

启动tomcat服务器进行拜访测试剖析

启动tomcat,而后在关上浏览器,在地址栏输出拜访地址,获取服务端数据并进行出现,接下来点击页面上的删除按钮进行测试。

购物券增加业务设计实现

业务形容

在购物券页面中设计增加表单,而后点击表单中的Save 按钮时将表单数据异步提交到服务端进行保留,如图所示:

业务时序设计及剖析

在购物券页面,输出购物券信息,而后提交到服务端进行保留,其时序剖析如图所示:

DAO接口办法设计及实现

在VoucherDao中增加用于保留商品信息的接口办法,代码如下:

int insertObject(Voucher entity);

在VoucherMapper文件中增加insertObject办法对应的SQL映射,代码如下:

<?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.cy.retail.voucher.dao.VoucherDao">    <insert id="insertObject">        insert into tb_voucher        (deno,requirement,startTime,endTime,maxNum,remark,createdTime)        values        (#{deno},#{requirement},#{startTime},#{endTime},#{maxNum},#{remark},now())    </insert></mapper>

Service接口办法设计及实现

在VoucherService接口中增加业务办法,用于实现购物券信息增加,代码如下:

int saveObject(Voucher entity);

在VoucherSerivceImpl类中增加接口办法实现,代码如下:

@Overridepublic int saveObject(Voucher entity) {    return voucherDao.insertObject(entity);}

Controller类中办法设计及实现

在VoucherController类中增加用于解决增加申请的办法,代码如下:

@PostMapping("/voucher/doSaveObject")public ResponseResult doSaveObject(@RequestBody Voucher entity){    System.out.println(entity);    voucherService.saveObject(entity);    return new ResponseResult("save ok");}

购物券页面表单元素设计及事件处理

在voucher.html页面代码中设计增加表单,代码如下:

<div>    <form>        <input type="hidden" v-model="id">        <div class="form-group">            <label for="denoId">面值</label>            <input type="text" v-model="deno" class="form-control" id="denoId" placeholder="面值">        </div>        <div class="form-group">            <label for="requirementId">利用条件</label>            <input type="text" v-model="requirement" class="form-control" id="requirementId" placeholder="利用条件">        </div>        <div class="form-group">            <label for="startTimeId">起始日期</label>            <input type="text" v-model="startTime" class="form-control" id="startTimeId" placeholder="起始日期">        </div>        <div class="form-group">            <label for="endTimeId">截至日期</label>            <input type="text" v-model="endTime" class="form-control" id="endTimeId" placeholder="截至日期">        </div>        <div class="form-group">            <label for="maxNumId">最大数量</label>            <input type="text" v-model="maxNum" class="form-control" id="maxNumId" placeholder="最大数量">        </div>        <div class="form-group">            <label for="maxNumId">备注</label>            <textarea v-model="remark" class="form-control" id="remarkId" placeholder="备注"></textarea>        </div>        <div class="form-group">            <input type="button" @click="doSaveOrUpdate" value="Save Data" class="btn btn-primary"/>        </div>    </form></div>

在Vue对象的Data区增加属性数据,代码如下:

deno:"",requirement:"",startTime:"",endTime:"",maxNum:"",remark:"",

在Vue对象中的Methods区,增加保留按钮事件处理函数,代码如下:
doSaveOrUpdate(){

    let url="voucher/doSaveObject";    let params={"id":this.id,"deno":this.deno,"requirement":this.requirement,"startTime":this.startTime,"endTime":this.endTime,"maxNum":this.maxNum,"remark":this.remark};    console.log(params);    axios.post(url,params).then(function(result){        alert(result.data.message);        this.vm.doFindPageObjects();        this.vm.id="";        this.vm.deno="";        this.vm.requirement="";        this.vm.startTime="";        this.vm.endTime="";        this.vm.maxNum="";        this.vm.remark="";    })}

购物券批改业务设计实现

业务形容

在购物券页面中设计批改按钮,并在点击批改按钮时候基于id查问购物券信息,而后出现在表单中,如图所示:

业务时序设计及剖析

基于用户更新设计其执行时序。

Dao接口办法设计及实现

在VoucherDao中增加基于id查问和更新的办法,代码如下:

@Select("select * from tb_voucher where id=#{id}")Voucher findById(Integer id);
int updateObject(Voucher entity);

将updateObject办法的SQL映射增加到映射文件(倡议SQL内容比拟多的写到映射文件),代码如下:

<update id="updateObject">    update tb_voucher    set     deno=#{deno},     requirement=#{requirement},     startTime=#{startTime},     endTime=#{endTime},     maxNum=#{maxNum},     remark=#{remark}    where id=#{id}</update>

Service接口办法设计及实现

在VoucherService中增加基于id查问和更新的办法,代码如下:

Voucher findById(Integer id);
int updateObject(Voucher entity);

在VoucherServiceImpl类中增加基于id查问和更新的办法,代码如下:

@Overridepublic Voucher findById(Integer id) {    return voucherDao.findById(id);}
@Overridepublic int updateObject(Voucher entity) {    return voucherDao.updateObject(entity);}

Controller类中办法设计及实现

在VoucherController类中增加解决基于id的查问申请办法和更新购物券信息的办法,代码如下:

@GetMapping("/voucher/doFindById/{id}")public ResponseResult doFindById(@PathVariable Integer id){    Voucher voucher=voucherService.findById(id);    return new ResponseResult(voucher);}
@PostMapping("/voucher/doUpdateObject")public ResponseResult doUpdateObject(@RequestBody Voucher entity){    voucherService.updateObject(entity);    return new ResponseResult("update ok");}

Voucher页面中更新设计设计及实现

在voucher页面设计中,在vue对象中的methods区增加基于id的查问申请办法,代码如下:

doFindById(id){    let url=`voucher/doFindById/${id}`;    axios.get(url).then(function(result){        console.log(result.data);        this.vm.id=result.data.data.id;        this.vm.deno=result.data.data.deno;        this.vm.requirement=result.data.data.requirement;        this.vm.startTime=result.data.data.startTime;        this.vm.endTime=result.data.data.endTime;        this.vm.maxNum=result.data.data.maxNum;        this.vm.remark=result.data.data.remark;    })}

在voucher页面设计中,在vue对象中的methods区批改doSaveOrUpdate办法,代码如下:

doSaveOrUpdate(){    let url=this.id?"voucher/doUpdateObject":"voucher/doSaveObject";    let params={"id":this.id,"deno":this.deno,"requirement":this.requirement,"startTime":this.startTime,"endTime":this.endTime,"maxNum":this.maxNum,"remark":this.remark};    console.log(params);    axios.post(url,params).then(function(result){        alert(result.data.message);        this.vm.doFindPageObjects();        this.vm.id="";        this.vm.deno="";        this.vm.requirement="";        this.vm.startTime="";        this.vm.endTime="";        this.vm.maxNum="";        this.vm.remark="";    })}

启动服务器进行拜访测试剖析

总结(Summary)

本大节重点解说了SpringBoot工程下MyBatis,SpringMVC,Vue技术的综合利用,重点了解其业务实现过程以及问题的解决过程。