最后:学习总结——MyBtis知识脑图(纯手绘xmind文档)
学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。下方即为我手绘的MyBtis知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的MyBtis知识脑图原件(包括上方的面试解析xmind文档)
除此之外,前文所提及的Alibaba珍藏版mybatis手写文档以及一本小小的MyBatis源码分析文档——《MyBatis源码分析》等等相关的学习笔记文档,也皆可分享给认可的朋友!
,{field: ‘stockCount’, title: ‘秒杀库存’}
,{field: ‘startDate’, title: ‘活动开始时间’}
,{field: ‘endDate’, title: ‘活动结束时间’}
,{field: ‘goodsName’, title: ‘商品名称’}
]]
});
呈现界面:
二、秒杀商品添加
=========
1、后端:接收前端添加秒杀商品的数据
①、实体类vo:SeckillGoodsVo
private List<Map<String,Object>> goods;
修改实体类时间的类型:SeckillGoods
@ApiModelProperty(“秒杀开始时间”)
@TableField(“start_date”)
@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
private Timestamp startDate;
@ApiModelProperty(“秒杀结束时间”)
@TableField(“end_date”)
@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”)
private Timestamp endDate;
②、mapper层:SeckillGoodsMapper
int addGoods(SeckillGoodsVo seckillGoodsVo);
③、mapper.xml层:SeckillGoodsMapper
批量插入秒杀商品的sql语句:
insert into t_seckill_goods(goods_id, seckill_price, stock_count, start_date, end_date)
values
(#{g.gid},#{g.goodsPrice},#{g.goodsStock},#{startDate},#{endDate})
④、service层
ISeckillGoodsService:
ResponseResult<List> addGoods(SeckillGoodsVo seckillGoodsVo);
SeckillGoodsServiceImpl:
@Override
public ResponseResult<List> addGoods(SeckillGoodsVo seckillGoodsVo) {
int goods=seckillGoodsMapper.addGoods(seckillGoodsVo);
return ResponseResult.success(goods);
}
⑤、controller层
@RequestMapping(“/add”)
public ResponseResult<List> add(@RequestBody SeckillGoodsVo seckillGoodsVo){
return seckillGoodsService.addGoods(seckillGoodsVo);
}
2、前端
①、定义数据与刷新、添加
goodsList.js:
var layer,row,seckill_table
// 添加秒杀商品
$(“#seckill_add”).click(()=>{
layer.open({
type:2,
content: ‘/goods/SeckillGoodsOperate’,
area: [‘800px’,‘600px’]
})
})
// 秒杀商品刷新
var seckill_reload = ()=> {
seckill_table.reload({
page:{
curr:1 //current
}
});
}
var layer,row,seckill_table
layui.define(()=>{
let table=layui.table
layer=layui.layer
let $=layui.jquery
let normal_table=table.render({
elem: ‘#normal_goods’
,height: 500
,url: ‘/goods/queryAll’ //数据接口
,page: true //开启分页
,parseData(res){ //res 即为原始返回的数据
return {
“code”: res.code===200?0:1, //解析接口状态
“msg”: res.message, //解析提示文本
“count”: res.total, //解析数据长度
“data”: res.data //解析数据列表
};
},
//用于对分页请求的参数:page、limit重新设定名称
request: {
pageName: ‘page’ //页码的参数名称,默认:page
,limitName: ‘rows’ //每页数据量的参数名,默认:limit
}
,cols: [[ //表头
{field: ‘gid’, title: ‘商品编号’, width:80, sort: true, fixed: ‘left’}
,{field: ‘goodsName’, title: ‘商品名字’}
,{field: ‘goodsTitle’, title: ‘商品标题’}
,{field: ‘goodsImg’,
title: ‘商品图片’,
width:200,
templet: (goods) => <b onmouseover='showImg("${goods.goodsImg}",this)'>
+ goods.goodsImg + </b>
}
,{field: ‘goodsDetail’, title: ‘商品详情’}
,{field: ‘goodsPrice’, title: ‘商品价格’, sort: true}
,{field: ‘goodsStock’, title: ‘商品库存’, sort: true}
,{field: ‘operate’, title: ‘商品操作’,toolbar: ‘#button_1’}
]]
});
// 刷新表格
let reloadTable=()=>{
let goodsName=$(“#normal_value”).val()
// 【JS】自动化渲染的重载,重载表格
normal_table.reload({
where: {
//设定异步数据接口的额外参数,height: 300
goodsName
},
page:{
curr:1 //current
}
});
}
// 搜索
$(“#normal_search”).click(reloadTable)
// 增加
$(“#normal_add”).click(()=>{
row = null
openDialog()
})
//工具条事件
table.on(‘tool(normal_goods)’, function(obj) { //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter=“对应的值”
let data = obj.data; //获得当前行数据
let layEvent = obj.event; //获得 lay-event 对应的值(也可以是表头的 event 参数对应的值)
let tr = obj.tr; //获得当前行 tr 的 DOM 对象(如果有的话)
if (layEvent === ‘normal_del’) { //删除
row = data//获得当前行的数据
let url=“/goods/del/”+data.gid
layer.confirm(‘确定删除吗?’,{title:‘删除’}, function(index){
//向服务端发送删除指令og
$.getJSON(url,{gid:data.gid}, function(ret){
layer.close(index);//关闭弹窗
reloadTable()
});
layer.close(index);//关闭弹窗
});
}
if (layEvent === ‘normal_edit’) { //编辑
row = data
openDialog()
}
})
// 页面弹出
let openDialog=()=>{
// 如果是iframe层
layer.open({
type: 2,
content: ‘/goods/goodsOperate’, //这里content是一个URL,如果你不想让iframe出现滚动条,你还可以content: [‘http://sentsin.com’, ‘no’]
area:[‘800px’,‘600px’],
btn: [‘确定’,‘取消’],
yes(index,layero){
let url=“/goods/insert”
// 拿到表格数据
let data=$(layero).find(“iframe”)[0].contentWindow.getFormData()
if(row) {
url=“/goods/edit”
}
$.ajax({
url,
data,
datatype: “json”,
success(res){
layer.closeAll()
reloadTable()
layer.msg(res.message)
}
})
}
});
}
// -------------------------秒杀商品-------------------------------------------
seckill_table=table.render({
elem: ‘#seckill_goods’
,height: 500
,url: ‘/seckillGoods/queryAll’ //数据接口
,parseData(res){ //res 即为原始返回的数据
return {
“code”: res.code===200?0:1, //解析接口状态
“msg”: res.message, //解析提示文本
“count”: res.total, //解析数据长度
“data”: res.data //解析数据列表
};
},
cols: [[ //表头
{field: ‘id’, title: ‘秒杀商品编号’, width:80, sort: true}
,{field: ‘goodsId’, title: ‘商品名字id’}
,{field: ‘seckillPrice’, title: ‘秒杀价格’}
,{field: ‘stockCount’, title: ‘秒杀库存’}
,{field: ‘startDate’, title: ‘活动开始时间’}
,{field: ‘endDate’, title: ‘活动结束时间’}
,{field: ‘goodsName’, title: ‘商品名称’}
]]
});
// 添加秒杀商品
$(“#seckill_add”).click(()=>{
layer.open({
type:2,
content: ‘/goods/SeckillGoodsOperate’,
area: [‘800px’,‘600px’]
})
})
})
// 图片显示
let showImg = (src,obj)=> {
layer.tips(<img src="${src}" width="100px">
, obj);
}
// 秒杀商品刷新
var seckill_reload = ()=> {
seckill_table.reload({
page:{
curr:1 //current
}
});
}
②、增加秒杀商品弹出页面样式
保 存
③、实现增加秒杀商品
seckillGoodsOperate.js:
layui.define(()=>{
let table=layui.table
let laydate = layui.laydate
let $=layui.jquery
let layer=layui.layer
// 读取普通商品
table.render({
elem: ‘#tb_goods’
,height: 500
,url: ‘/goods/queryAll’ //数据接口
,page: true //开启分页
,parseData(res){ //res 即为原始返回的数据
return {
“code”: res.code===200?0:1, //解析接口状态
“msg”: res.message, //解析提示文本
“count”: res.total, //解析数据长度
“data”: res.data //解析数据列表
};
},
//用于对分页请求的参数:page、limit重新设定名称
request: {
pageName: ‘page’ //页码的参数名称,默认:page
,limitName: ‘rows’ //每页数据量的参数名,默认:limit
}
,cols: [[ //表头
// 全选按钮
{field: ‘’, type:“checkbox”}
,{field: ‘gid’, title: ‘商品编号’, width:80}
,{field: ‘goodsName’, title: ‘商品名字’}
,{field: ‘goodsTitle’, title: ‘商品标题’}
,{field: ‘goodsDetail’, title: ‘商品详情’}
,{field: ‘goodsPrice’, title: ‘商品价格’, sort: true}
,{field: ‘goodsStock’, title: ‘商品库存’, sort: true}
]]
});
// 构建时间选择器
//执行一个laydate实例
laydate.render({
elem: ‘#dt’, //指定元素
type: “datetime”,
range: “~”
});
$(“#btn_save”).click(()=>{
// 获取时间
let val=$(“#dt”).val()
if(!val){
layer.msg(“请选择时间”)
return
}
// 解析时间2022-2-2 ~2022-5-2
let startDate=new Date(val.split(“~”)[0]).getTime()
let endDate=new Date(val.split(“~”)[1]).getTime()
// 获得选中的普通商品,获取选中行的数据
let rows= table.checkStatus(‘tb_goods’).data; //idTest 即为基础参数 id 对应的值
if(!rows||rows.length===0){
layer.msg(“请选择数据”)
return
}
layer.prompt(function(value, index, elem){
// 修改每个商品的数量
rows.forEach(e=>{
e.goodsStock=value
})
let data={
startDate,
endDate,
goods:rows
}
// 访问后台的秒杀商品的接口
$.ajax({
url: “/seckillGoods/add”,
contentType:‘application/json’,
data: JSON.stringify(data),
datatype:“json”,//返回类型
type:“post”,
success(res){
parent.seckill_reload()
layer.closeAll()
parent.layer.closeAll()
layer.msg(res.message)
}
})
});
})
})
④、展示结果
增加成功:
三、秒杀商品的操作
==========
1、后端操作秒杀单个商品详情
①、mapper层
SeckillGoodsMapper:
Map<String,Object> querySeckillGoodsById(Long id);
mapper.xml文件:SeckillGoodsMapper.xml
select sg.id,
sg.goods_id,
sg.seckill_price,
sg.stock_count,
sg.start_date,
sg.end_date,
g.goods_img,
g.goods_title,
g.goods_detail,
g.goods_name,
(
case
when current_timestamp < sg.start_date then 0
when (current_timestamp between sg.start_date and sg.end_date) then 1
when current_timestamp > sg.end_date then 2
end
) goods_status
from t_goods g,
t_seckill_goods sg
where g.gid = sg.goods_id
and sg.id = #{0}
②、service层
ISeckillGoodsService:
Map<String,Object> querySeckillGoodsById(Long id);
SeckillGoodsServiceImpl:
@Override
public Map<String, Object> querySeckillGoodsById(Long id) {
return seckillGoodsMapper.querySeckillGoodsById(id);
}
③、controller层:SeckillGoodsController
package com.example.seckill.controller;
import com.example.seckill.service.ISeckillGoodsService;
import com.example.seckill.util.response.ResponseResult;
import com.example.seckill.vo.SeckillGoodsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
-
-
秒杀商品信息表 前端控制器
-
@author lv
-
@since 2022-03-19
*/
@Controller
@RequestMapping(“/seckillGoods”)
public class SeckillGoodsController {
@Autowired
private ISeckillGoodsService seckillGoodsService;
// 返回json
@ResponseBody
@RequestMapping(“/queryAll”)
public ResponseResult<List> queryAll(){
return seckillGoodsService.queryAll();
}
@ResponseBody
@RequestMapping(“/add”)
public ResponseResult<List> add(@RequestBody SeckillGoodsVo seckillGoodsVo){
return seckillGoodsService.addGoods(seckillGoodsVo);
}
// 正常跳转界面
@RequestMapping(“/query/{id}”)
public ModelAndView querySeckillGoodsById(@PathVariable(“id”) Long id) {
ModelAndView mv = new ModelAndView(“/goods/goodsSeckill”);
mv.addObject(“goods”, seckillGoodsService.querySeckillGoodsById(id));
return mv;
}
}
2、前端展示
①、在goodsList.js增加列的操作
{
field: ‘’, title: ‘操作’, width: 140,
templet: function (d) {
return `
`;}
}
②、添加秒杀详情界面 :goodsSkill.ftl
<#include “…/common/head.ftl”/>
${goods[‘goods_name’]}
商品标题${goods[‘goods_title’]}
商品价格${goods[‘seckill_price’]}
开始时间${goods[‘start_date’]?string(“yyyy-MM-dd HH:mm:ss”)}
${goods[‘end_date’]?string(“yyyy-MM-dd HH:mm:ss”)}
<#if goods[‘goods_status’]==0>
活动未开始
<#elseif goods[‘goods_status’]==1>
活动热卖中
立即抢购
<#else>
活动已结束
</#if>
③、实现:goodsSkill.js
let layer, form, $;
layui.define(() => {
layer = layui.layer
form = layui.form
$ = layui.jquery
$(‘#buy’).click(() => {
$.ajax({
url: ‘/seckillOrder/addOrder’,
data: {goodsId: $(‘#goodsId’).val()},
dataType: ‘json’,
type: ‘post’,
async: false,
success: function (rs) {
if (rs.code === 200)
layer.msg(rs.message)
else
layer.msg(rs.message)
}
})
});
})
④、展示效果
点击秒杀:
3、后端操作秒杀抢购功能
①、导入雪花id工具包:SnowFlake
package com.example.seckill.util;
@SuppressWarnings(“all”)
public class SnowFlake {
/**
- 起始的时间戳
*/
private final static long START_STMP = 1480166465631L;
/**
- 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATACENTER_BIT = 5;//数据中心占用的位数
/**
- 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
/**
- 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
private long datacenterId; //数据中心
private long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
public SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException(“datacenterId can’t be greater than MAX_DATACENTER_NUM or less than 0”);
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException(“machineId can’t be greater than MAX_MACHINE_NUM or less than 0”);
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
public static void main(String[] args) {
SnowFlake snowFlake = new SnowFlake(2, 3);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
System.out.println(snowFlake.nextId());
}
System.out.println(System.currentTimeMillis() - start);
}
/**
-
产生下一个ID
-
@return
最后
由于文案过于长,在此就不一一介绍了,这份Java后端架构进阶笔记内容包括:Java集合,JVM、Java并发、微服务、SpringNetty与 RPC 、网络、日志 、Zookeeper 、Kafka 、RabbitMQ 、Hbase 、MongoDB、Cassandra 、Java基础、负载均衡、数据库、一致性算法、Java算法、数据结构、分布式缓存等等知识详解。
本知识体系适合于所有Java程序员学习,关于以上目录中的知识点都有详细的讲解及介绍,掌握该知识点的所有内容对你会有一个质的提升,其中也总结了很多面试过程中遇到的题目以及有对应的视频解析总结。
e = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
public SnowFlake(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException(“datacenterId can’t be greater than MAX_DATACENTER_NUM or less than 0”);
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException(“machineId can’t be greater than MAX_MACHINE_NUM or less than 0”);
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
public static void main(String[] args) {
SnowFlake snowFlake = new SnowFlake(2, 3);
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
System.out.println(snowFlake.nextId());
}
System.out.println(System.currentTimeMillis() - start);
}
/**
-
产生下一个ID
-
@return
最后
由于文案过于长,在此就不一一介绍了,这份Java后端架构进阶笔记内容包括:Java集合,JVM、Java并发、微服务、SpringNetty与 RPC 、网络、日志 、Zookeeper 、Kafka 、RabbitMQ 、Hbase 、MongoDB、Cassandra 、Java基础、负载均衡、数据库、一致性算法、Java算法、数据结构、分布式缓存等等知识详解。
[外链图片转存中…(img-Bw7G9pm3-1714894863474)]
本知识体系适合于所有Java程序员学习,关于以上目录中的知识点都有详细的讲解及介绍,掌握该知识点的所有内容对你会有一个质的提升,其中也总结了很多面试过程中遇到的题目以及有对应的视频解析总结。
[外链图片转存中…(img-943I1QMM-1714894863475)]
[外链图片转存中…(img-epGycb5b-1714894863475)]