Java秒杀简单设计二:数据库表Dao层设计

上一篇中搭建springboot项目环境和设计数据库表  https://www.cnblogs.com/taiguyiba/p/9791431.html

在此基础上设计数据库表Dao层代码

1.数据库表设计

项目涉及到两张表,seckill:秒杀库存表,success_killed:秒杀成功明细表

seckill:秒杀库存表

CREATE TABLE `seckill`  (
`seckill_id` bigint() NOT NULL AUTO_INCREMENT COMMENT '商品库存ID',
`name` varchar() CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品名称',
`number` int() NOT NULL COMMENT '库存数量',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`start_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '秒杀开始时间',
`end_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '秒杀结束时间',
PRIMARY KEY (`seckill_id`) USING BTREE,
INDEX `idx_start_time`(`start_time`) USING BTREE,
INDEX `idx_end_time`(`end_time`) USING BTREE,
INDEX `idx_create_time`(`create_time`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '秒杀库存表';

插入数据:

INSERT INTO `seckill` VALUES (, '1000元秒杀iphone6', , '2018-10-14 22:36:57', '2016-01-01 00:00:00', '2016-01-02 00:00:00');
INSERT INTO `seckill` VALUES (, '800元秒杀ipad', , '2018-10-14 22:36:57', '2016-01-01 00:00:00', '2016-01-02 00:00:00');
INSERT INTO `seckill` VALUES (, '6600元秒杀mac book pro', , '2018-10-14 22:36:57', '2016-01-01 00:00:00', '2016-01-02 00:00:00');
INSERT INTO `seckill` VALUES (, '7000元秒杀iMac', , '2018-10-14 22:36:57', '2016-01-01 00:00:00', '2016-01-02 00:00:00');

success_killed:秒杀成功明细表

CREATE TABLE `success_killed`  (
`seckill_id` bigint() NOT NULL COMMENT '秒杀商品ID',
`user_phone` bigint() NOT NULL COMMENT '用户手机号',
`state` tinyint() NOT NULL DEFAULT - COMMENT '状态标识:-1:无效 0:成功 1:已付款 2:已发货',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`seckill_id`, `user_phone`) USING BTREE,
INDEX `idx_create_time`(`create_time`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '秒杀成功明细表';

2.Dao设计

首先在 SeckillApplication.java文件中添加Mapper扫描注解@MapperScan("com.seckill.dao")

package com.seckill;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan("com.seckill.dao")
public class SeckillApplication { public static void main(String[] args) {
SpringApplication.run(SeckillApplication.class, args);
}
}

创建SeckillDao.java文件:

包括减库存、查询、使用存储过程秒杀等方法

package com.seckill.dao;

import java.util.Date;
import java.util.List;
import java.util.Map; import org.apache.ibatis.annotations.Param; import com.seckill.entity.Seckill; public interface SeckillDao { /**
* 减库存
* @param seckillId
* @param killTime
* @return 如果影响行数>1,表示更新库存的记录行数
*/
int reduceNumber(@Param("seckillId") long seckillId,@Param("killTime") Date killTime);
/**
* 根据id查询秒杀的商品信息
* @param seckillId
* @return
*/
Seckill queryById(@Param("seckillId") long seckillId);
/**
* 根据偏移量查询秒杀商品列表
* @param offset
* @param limit
* @return
*/
List<Seckill> queryAll(@Param("offset") int offset,@Param("limit")int limit);
/**
* 使用存储过程执行秒杀
* @param paramMap
*/
void killByProcedure(Map<String,Object> paramMap); }

 注意:Java没有保存形参的记录,queryAll(int offset,int limit) ==> queryAll(arg0,arg1),所以在多个参数的时候,需要使用注解:@Param

创建 SuccessKilledDao.java文件

package com.seckill.dao;

import org.apache.ibatis.annotations.Param;

import com.seckill.entity.SuccessKilled;

public interface SuccessKilledDao {

    /**
* 插入购买明细,可过滤重复
* @param seckillId
* @param userPhone
* @return 插入的行数
*/
int insertSuccessKilled(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);
/**
* 根据秒杀商品ID查询明细SuccessKilled对象, 携带了Seckill秒杀产品对象
* @param seckillId
* @param userPhone
* @return
*/
SuccessKilled queryByIdWithSeckill(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);
}

创建SeckillDao.xml文件

<?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.seckill.dao.SeckillDao">
<update id="reduceNumber">
UPDATE seckill
SET number = number -
WHERE seckill_id = #{seckillId}
AND start_time <![CDATA[ <= ]]> #{killTime}
AND end_time >= #{killTime}
AND number >
</update> <select id="queryById" resultType="Seckill" parameterType="long">
SELECT *
FROM seckill
WHERE seckill_id = #{seckillId}
</select> <select id="queryAll" resultType="Seckill">
SELECT *
FROM seckill
ORDER BY create_time DESC
limit #{offset},#{limit}
</select>
<!-- 使用mybatis调用存储过程 -->
<select id="killByProcedure" statementType="CALLABLE">
call execute_seckill(
#{seckillId,jdbcType=BIGINT,mode=IN},
#{phone,jdbcType=BIGINT,mode=IN},
#{killTime,jdbcType =TIMESTAMP,mode=IN},
#{result,jdbcType=INTEGER,mode=OUT}
)
</select>
</mapper>

SuccessKilledDao.xml文件

<?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.seckill.dao.SuccessKilledDao">
<insert id="insertSuccessKilled">
<!--当出现主键冲突时(即重复秒杀时),会报错;不想让程序报错,加入ignore-->
INSERT ignore INTO success_killed(seckill_id,user_phone,state)
VALUES (#{seckillId},#{userPhone},0)
</insert> <select id="queryByIdWithSeckill" resultType="SuccessKilled">
<!--根据seckillId查询SuccessKilled对象,并携带Seckill对象-->
<!--如何告诉mybatis把结果映射到SuccessKill属性同时映射到Seckill属性-->
<!--可以自由控制SQL语句-->
SELECT
sk.seckill_id,
sk.user_phone,
sk.create_time,
sk.state,
s.seckill_id "seckill.seckill_id",
s.name "seckill.name",
s.number "seckill.number",
s.start_time "seckill.start_time",
s.end_time "seckill.end_time",
s.create_time "seckill.create_time"
FROM success_killed sk
INNER JOIN seckill s ON sk.seckill_id = s.seckill_id
WHERE sk.seckill_id=#{seckillId} and sk.user_phone=#{userPhone}
</select>
</mapper>

Java秒杀简单设计二:数据库表和Dao层设计的更多相关文章

  1. Java秒杀简单设计三:数据封装类

    上一篇https://www.cnblogs.com/taiguyiba/p/9828984.html 整合了数据库表和Dao层代码 这一篇继续设计数据封装类: 涉及到获取秒杀地址,查询,返回秒杀结果 ...

  2. Java秒杀简单设计一:搭建springboot环境

    项目参考:慕课网  https://www.imooc.com/learn/587 Java秒杀 开发环境 JDK1.8.Maven.Mysql.Eclipse.SpringBoot2.0.5.myb ...

  3. 物理数据模型(PDM)->概念数据模型 (CDM)->面向对象模型 (OOM):适用于已经设计好数据库表结构了。

    物理数据模型(PDM)->概念数据模型 (CDM)->面向对象模型 (OOM):适用于已经设计好数据库表结构了.   步骤如下: 一.反向生成物理数据模型PDM 开发环境 PowerDes ...

  4. facade层,service 层,domain层,dao 层设计

    转自http://fei-6666.iteye.com/blog/446247,记录下来 一,Service->DAO,只能在Service中注入DAO. 二,DAO只能操作但表数据,跨表操作放 ...

  5. Java秒杀简单设计四:service层设计

    接上一篇 https://www.cnblogs.com/taiguyiba/p/9829191.html  封装了系统传递的数据类和异常类 本文继续设计service层设计: 1.SeckillSe ...

  6. java实现excel表格导入数据库表

    导入excel就是一个上传excel文件,然后获取excel文件数据,然后处理数据并插入到数据库的过程 一.上传excel 前端jsp页面,我的是index.jsp 在页面中我自己加入了一个下载上传文 ...

  7. java工具类–自动将数据库表生成javabean

    最近和数据库的表打交道挺多的,因为暂时做的是接口活. 在这过程中发现要把表转换成对应的javabean类型,字段少的表还行,如果不小心碰到几十个字段的他妈的写起来就有点麻烦了,万一碰到几百个的呢,那不 ...

  8. java开发_mysql中获取数据库表描述_源码下载

    功能描述: 在mysql数据库中,有两张表: data_element_config , test_table 我们需要获取表:test_table表的描述信息,然后把描述信息插入到表:data_el ...

  9. EF 学习系列二 数据库表的创建和表关系配置(Fluent API、Data Annotations、约定)

    上一篇写了<Entity Farmework领域建模方式 3种编程方式>,现在就Code First 继续学习 1.数据库表的创建 新建一个MVC的项目,在引用右击管理NuGet程序包,点 ...

随机推荐

  1. Java编程思想学习笔记——字符串

    前言 字符串操作是计算机程序设计中最常见的行为. 不可变String String对象是不可变的 重载"+"与StringBuilder String对象是不可变的,可以给Stri ...

  2. Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)

    [Android布局学习系列]   1.Android 布局学习之——Layout(布局)详解一   2.Android 布局学习之——Layout(布局)详解二(常见布局和布局参数)   3.And ...

  3. python对日志处理的封装

    一个适应性范围较广的日志处理 # coding=utf8 """ @author bfzs """ import os import log ...

  4. 手机CPU

    说起手机CPU的历史,笔者给大家提一个问题:"世界上第一款智能手机是什么呢?"相信很多人的答案是爱立信的R380或诺基亚的7650,但都不对,真正的首款智能手机是由摩托罗拉在200 ...

  5. N76E003的定时器/计数器 0和1

    定时器/计数器 0和1N76E003系列定时器/计数器 0和1是2个16位定时器/计数器.每个都是由两个8位的寄存器组成的16位计数寄存器. 对于定时器/计数器0,高8位寄存器是TH0. 低8位寄存器 ...

  6. LINUX网络之ifconfig命令与ping

    ifconfig命令 网络配置 ifconfig命令被用于配置和显示Linux内核中网络接口的网络参数.用ifconfig命令配置的网卡信息,在网卡重启后机器重启后,配置就不存在.要想将上述的配置信息 ...

  7. thinkjs2.2中的定时任务

    暂且先讨论定时任务的其中两种实现方法: 1.setInterval() setInterval()可按照指定的周期(毫秒数计)来调用函数或者计算表达式: setInterval()方法会不停的调用该函 ...

  8. 《C++ Primer Plus》第17章 输入、输出和文件 学习笔记

    流是进出程序的字节流.缓冲区是内存中的临时存储区域,是程序与文件或其他I/O设备之间的桥梁.信息在缓冲区和文件之间传输时,将使用设备(如磁盘驱动器)处理效率最高的尺寸以大块数据的方式进行传输.信息在缓 ...

  9. c++对象的生命周期

    C++ 的new 运算子和C 的malloc 函数都是为了配置内存,但前者比之后者的优点是,new 不但配置对象所需的内存空间时,同时会引发构造式的执行. 所谓构造式(constructor),就是对 ...

  10. Android Studio中R报错(cnanot resolve symbol R)

    我的解决办法: Tools -> Android -> Sync Project with Gradle Files Build -> Clean Project 然后就好了 PS: ...