共计 10228 个字符,预计需要花费 26 分钟才能阅读完成。
业务形容
基于 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 '面值',
`condition` 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 condition;
/** 起始工夫 */
@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 getCondition() {return condition;}
public void setCondition(Integer condition) {this.condition = condition;}
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 +
", condition=" + condition +
", 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.condition}}</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 注解对参数进行形容。
Vouter 页面上删除按钮事件处理
在 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,而后在关上浏览器,在地址栏输出拜访地址,获取服务端数据并进行出现,接下来点击页面上的删除按钮进行测试。