博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java高并发秒杀Api-业务分析与DAO层构建2
阅读量:7081 次
发布时间:2019-06-28

本文共 12038 字,大约阅读时间需要 40 分钟。

章节目录

  • DAO 设计编码
    • 数据库设计与编码
    • DAO层实体和接口编码
    • 基于mybatis实现DAO理论
    • 基于mybatis实现DAO接口-1
    • mybatis整合Spring
    • DAO层编码解析

Dao 设计编码

1.pom.xml 引入项目依赖的包

4.0.0
org.seckill
seckill
war
1.0
seckill Maven Webapp
http://maven.apache.org
junit
junit
4.11
test
org.slf4j
slf4j-api
1.7.12
ch.qos.logback
logback-core
1.1.2
ch.qos.logback
logback-classic
1.1.2
mysql
mysql-connector-java
5.1.35
runtime
c3p0
c3p0
0.9.1.2
org.mybatis
mybatis
3.3.0
org.mybatis
mybatis-spring
1.2.3
taglibs
standard
1.1.2
jstl
jstl
1.2
com.fasterxml.jackson.core
jackson-databind
2.5.4
javax.servlet
javax.servlet-api
3.1.0
org.springframework
spring-core
4.1.7.RELEASE
org.springframework
spring-beans
4.1.7.RELEASE
org.springframework
spring-context
4.1.7.RELEASE
org.springframework
spring-jdbc
4.1.7.RELEASE
org.springframework
spring-tx
4.1.7.RELEASE
org.springframework
spring-web
4.1.7.RELEASE
org.springframework
spring-webmvc
4.1.7.RELEASE
org.springframework
spring-test
4.1.7.RELEASE
seckill

2.数据库设计与编码

数据库脚本如下所示:

--数据库初始化脚本--创建数据库CREATE DATABASE seckill;--使用数据库use seckill;--创建秒杀库存表CREATE TABLE seckill(   `seckill_id` bigint not null AUTO_INCREMENT COMMENT '商品库存id',   `name` VARCHAR (120) not null COMMENT '商品名称',   `stock` int not null COMMENT '库存数量',   `start_time` TIMESTAMP NOT  NULL COMMENT '秒杀开始时间',   `end_time` TIMESTAMP  NOT NULL COMMENT '秒杀结束时间',   `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',   PRIMARY KEY (seckill_id),   key idx_start_time(start_time),   key idx_end_time(end_time),   key idx_create_time(create_time)) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒杀库存表';--初始化数据INSERT  INTO seckill(name,stock,start_time,end_time)VALUES ('1000元秒杀iphone x','100','2018-05-04 00:00:00','2018-05-05 00:00:00'),       ('500元秒杀ipad x','200','2018-05-04 00:00:00','2018-05-05 00:00:00'),       ('300元秒杀小米4','300','2018-05-04 00:00:00','2018-05-05 00:00:00'),       ('200元秒杀小米note','400','2018-05-04 00:00:00','2018-05-05 00:00:00');--秒杀成功明细表CREATE TABLE success_killed(  `seckill_id` bigint NOT NULL COMMENT '秒杀商品id',  `user_phone` VARCHAR(11) NOT NULL COMMENT '用户手机号',  `state` tinyint NOT NULL DEFAULT -1 COMMENT '状态标志:-1:无效 0:成功 1:已付款',  `create_time` TIMESTAMP NOT NULL COMMENT '创建时间',  PRIMARY KEY (seckill_id,user_phone),/*联合主键*/  key idx_create_time(create_time)) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒杀成功明细表';--连接数据库的控制台mysql -u root -p

3.DAO层实体与接口编码

img_4d4b795c7bd0b0d2c71f8a1d9f783726.png
数据库与实体类映射

3.1MyBatis 实现DAO接口的方式

  • Mapper自动实现DAO接口
    sql直接编写,注解sql(sql更改,原代码需要重新编译),xml方式,单独更新sql,源文件不需要重新编译。
  • API 编程方式自动实现DAO 接口

3.2 基于mybatis实现DAO接口-1

  • 全局mybatis-conf.xml
  • SecKillDao.xml编写
UPDATE seckill SET stock = stock - 1 WHERE seckill_id = #{secKillId} AND start_time #{killTime} AND end_time >= #{killTime} and stock > 0
  • SuccessKilledDao.xml 编写
INSERT ignore INTO success_killed(seckill_id,user_phone) VALUES (#{secKillId},#{userPhone})
  • entity实体层实现-SecKill、SuccessKilled
package org.seckill.domain;import java.util.Date;/** * 秒杀-库存表 entity */public class SecKill {    private long seckillId; //秒杀-商品id    private String name;    //秒杀-商品名字    private int stock;      //秒杀-商品库存    private Date startTime; //秒杀-开始时间    private Date endTime;   //秒杀-结束时间    private Date createTime; //秒杀-商品新建时间    public long getSeckillId() {        return seckillId;    }    public void setSeckillId(long seckillId) {        this.seckillId = seckillId;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getStock() {        return stock;    }    public void setStock(int stock) {        this.stock = stock;    }    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 Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    @Override    public String toString() {        return "SecKill{" +                "seckillId=" + seckillId +                ", name='" + name + '\'' +                ", stock=" + stock +                ", startTime=" + startTime +                ", endTime=" + endTime +                ", createTime=" + createTime +                '}';    }}
package org.seckill.domain;import java.util.Date;/** * 成功秒杀明细表-SuccessKilled */public class SuccessKilled {    private long secKillId;    //秒杀-成功的商品id    private String userPhone;  //秒杀-成功的用户手机号    private short state;       //秒杀-明细状态    private Date createTime;   //秒杀-秒杀成功的时间    //one(被秒杀商品)-to-many(秒杀记录)    private SecKill secKill;    public long getSecKillId() {        return secKillId;    }    public void setSecKillId(long secKillId) {        this.secKillId = secKillId;    }    public String getUserPhone() {        return userPhone;    }    public void setUserPhone(String userPhone) {        this.userPhone = userPhone;    }    public short getState() {        return state;    }    public void setState(short state) {        this.state = state;    }    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    public SecKill getSecKill() {        return secKill;    }    public void setSecKill(SecKill secKill) {        this.secKill = secKill;    }    @Override    public String toString() {        return "SuccessKilled{" +                "secKillId=" + secKillId +                ", userPhone='" + userPhone + '\'' +                ", state=" + state +                ", createTime=" + createTime +                '}';    }}
  • DAO层接口功能声明-SecKillDao、SuccessKilledDao
package org.seckill.dao;import org.seckill.domain.SecKill;import java.util.Date;import java.util.List;/** * 常用的操作 */public interface SecKillDao {    /**     * 功能:减库存     * @param secKillId     * @param killTime create_time?     * @return 如果影响行数>1,表示更新的记录行数     */    int reduceStock(long secKillId,Date killTime);    /**     * 根据秒杀商品id查询秒杀商品详情     * @param secKillId     * @return     */    SecKill queryById(long secKillId);    /**     * 根据偏移量查询秒杀商品列表,     * @param offset     * @param limit     * @return     */    List
queryAll(int offset,int limit);}
package org.seckill.dao;import org.seckill.domain.SuccessKilled;public interface SuccessKilledDao {    /**     * 功能:新增用户秒杀明细     * @param secKillId     * @param userPhone     * @return 插入的行数,禁止插入表示插入失败 则返回0     */    int insertSuccessKilled(long secKillId,long userPhone);    /**     * 功能:根据明细id查询具体的秒杀明细并携带秒杀商品对象     * @param secKillId     * @return     */    SuccessKilled queryByIdWithSecKill(long secKillId);}

MyBatis整合Spring

整合的目标:

  • 更少的编码
  • 更少的配置
  • 足够的灵活性
    1.mybatis优点
更少的编码、只写接口、不写实现

2.DAO层接口声明能显示说明很多事情

img_e30135972b761f4e01a3de640426198e.png
轻量级显式接口声明

更少的配置-别名

img_e871e8d92ca50763fbc90333b9ba5d4d.png
image.png

使用spring 提供的package-scan 扫描实体包下的所有实体类。可以简写resultType

更少的配置-配置扫描

  • 单独使用mybatis的场景下,配置文件扫描方式

<mapper resource="mapper/SecKillDao.xml">....

  • 使用spring 整合 mybatis 自动扫描配置文件,采用通配符的方式。

  • 自动实现DAO接口,DAO接口的实现类是自动注入至Spring 容器

足够的灵活性

img_94b027caef0949d158bc678731ed62bc.png
image.png

5.DAO层接口设计与SQL编写的反思

DAO - data access object 数据访问层的简称

这一层我们主要做的是核心数据操作的接口声明,以及SQL编写,并没有涉及到Service 业务逻辑层代码的编写。这样做的好处是什么呢?
主要有以下三点

  • 代码分层,DAO层只关注于核心数据操作的接口声明&SQL编写
  • 代码和SQL的分离,方便代码review
  • 业务逻辑层主要做事务控制、事务中完成DAO层的代码组合与拼接。每一层都可以做单元测试。

接下来详解mybatis 与 spring 整合编码的过程

转载地址:http://xtvml.baihongyu.com/

你可能感兴趣的文章
RequestMapping_Ant 路径
查看>>
java总结
查看>>
JavaScript选择器
查看>>
机器学习入门-K-means算法
查看>>
更简单的非递归遍历二叉树的方法
查看>>
ural 1073.Square Country(动态规划)
查看>>
Qt 多语言支持
查看>>
jquery中的事件
查看>>
python爬虫知识点总结(二十六)Scrapy+Tushare爬取微博股票数据
查看>>
rpm -qa 查找文件
查看>>
Linux文件管理相关命令
查看>>
C#中按指定质量保存图片的实例代码 24位深度
查看>>
实现winfrom进度条及进度信息提示,winfrom程序假死处理
查看>>
php 面向对象上课笔记
查看>>
php echo、print、print_r、printf、sprintf、var_dump的区别比较
查看>>
开发小程序随笔
查看>>
【Oracle】在WIN NT 64位环境下安装win64_11gR2_database。并用PL/SQL连接
查看>>
CentOS切换桌面模式和命令行模式
查看>>
noip2013火柴排序
查看>>
固定GridView的头
查看>>