乐趣区

关于springboot:15基于SpringMyBatisSpringBootVue技术实现购物券系统的增删改查操作

业务形容

基于 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 的创立并剖析其构造

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

#server
server.port=80
#spring datasource
spring.datasource.url=jdbc:mysql:///dbvoucher?serverTimezone=GMT%2B8&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

#spring mybatis
mybatis.mapper-locations=classpath:/mapper/*/*.xml

#spring logging
logging.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;
@Mapper
public 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;
@SpringBootTest
public 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;
@Service
public 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;
@SpringBootTest
public 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;
@RestController
public 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 类中增加接口办法实现,代码如下:

@Override
public 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 查问和更新的办法,代码如下:

@Override
public Voucher findById(Integer id) {return voucherDao.findById(id);
}
@Override
public 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 技术的综合利用,重点了解其业务实现过程以及问题的解决过程。

退出移动版