前言

该篇教程主要关注MyBatis实现底层的接口,把MyBatis交给Spring来托管。数据库连接池用的c3p0。数据库用的MySQL。主要有2个大类:秒杀商品的查询、秒杀明细的插入。

准备工作

1、数据库脚本。先初始化数据库,这里主要有2张表:seckill【秒杀商品表】、success_killed【秒杀记录明细表】。success_killed采用双主键seckill_id、user_phone。同一个商品同一个手机号只能秒杀一次,如果通过非法手段通过业务接口的话,则重复插入秒杀记录明细时会返回0。

-- 创建数据库
CREATE DATABASE seckill;
-- 使用数据库
use seckill;
CREATE TABLE seckill(
`seckill_id` BIGINT NOT NUll AUTO_INCREMENT COMMENT '商品库存ID',
`name` VARCHAR(120) NOT NULL COMMENT '商品名称',
`number` 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,number,start_time,end_time)
VALUES
('1000元秒杀iphone6',100,'2016-01-01 00:00:00','2016-01-02 00:00:00'),
('800元秒杀ipad',200,'2016-01-01 00:00:00','2016-01-02 00:00:00'),
('6600元秒杀mac book pro',300,'2016-01-01 00:00:00','2016-01-02 00:00:00'),
('7000元秒杀iMac',400,'2016-01-01 00:00:00','2016-01-02 00:00:00'); -- 秒杀成功明细表
-- 用户登录认证相关信息(简化为手机号)
CREATE TABLE success_killed(
`seckill_id` BIGINT NOT NULL COMMENT '秒杀商品ID',
`user_phone` BIGINT NOT NULL COMMENT '用户手机号',
`state` TINYINT NOT NULL DEFAULT -1 COMMENT '状态标识:-1:无效 0:成功 1:已付款 2:已发货',
`create_time` TIMESTAMP NOT NULL COMMENT '创建时间',
PRIMARY KEY(seckill_id,user_phone),/*联合主键*/
KEY idx_create_time(create_time)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='秒杀成功明细表';

   2、实现MyBatis配置文件并且交由Spring托管

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--使用jdbc的getGeneratedKeys获取自增主键值-->
<setting name="useGeneratedKeys" value="true"/>
<!--使用列别名替换列名,默认值true-->
<setting name="useColumnLabel" value="true"/>
<!--开启驼峰命名法 字段名seckill_Id 对应属性名seckillId -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>

spring-dao.xml

这里关键是sqlsessionfactory的配置,需要指定mybatis全局配置文件、mapper.xml文件位置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!--1、配置数据库相关参数-->
<context:property-placeholder location="classpath:jdbc.properties"/> <!--2、配置数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/> <!--数据库连接池最大连接数-->
<property name="maxPoolSize" value="30" />
<!--数据库连接池最小连接数-->
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动commit-->
<property name="autoCommitOnClose" value="false"/>
<!--获取连接超时时间-->
<property name="checkoutTimeout" value="1000"/>
<!--当获取连接失败时重试次数-->
<property name="acquireRetryAttempts" value="3"/>
</bean> <!--3、配置SqlSessionFactory-->
<bean id="sessionfactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--mybatis全局配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--扫描entity包-->
<property name="typeAliasesPackage" value="com.seckill.entity"/>
<!--扫描sql xml文件-->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean> <!--4、配置扫描Dao接口包,动态实现dao接口注入到spring容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--需要扫描的dao接口-->
<property name="basePackage" value="com.seckill.dao"/>
<!--注入sqlsessionfactory-->
<property name="sqlSessionFactoryBeanName" value="sessionfactory"/>
</bean>
</beans>

秒杀底层接口实现

1、实现接口。这里注意Param注解,当方法只有一个参数时不用指定,如果你需要给mapper里传多个参数则指定,也可以用HashMap传参。

public interface SeckillDao {

    /**减库存**/
int reduceNumber(@Param("seckillId") long seckillId,@Param("killTime") Date killTime); /**查询秒杀商品详情**/
Seckill queryById(long seckillId); /**查询所有秒杀商品**/
List<Seckill> queryAll(@Param("offset") int offset,@Param("limit") int limit); } public interface SuccessKillDao { /**
* 插入秒杀商品明细
* **/
int insertSuccessKilled(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone); /**
* 根据商品id查询商品秒杀明细,并且同时返回商品明细
* **/
SuccessKilled queryByIdWithSeckill(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone); }

2、秒杀实现。也就是mapper目录下的*.xml文件。

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-1
where seckill_Id=#{seckillId}
and start_time <![CDATA[ <= ]]> #{killTime}
and end_time <![CDATA[ >= ]]> #{killTime}
and number>0
</update> <select id="queryById" resultType="Seckill">
select seckill_id,name,number,start_time,end_time,create_time
from seckill
where seckill_id=#{seckillId}
</select> <select id="queryAll" resultType="Seckill">
select seckill_id,name,number,start_time,end_time,create_time
from seckill
order by create_time
limit #{offset},#{limit}
</select>
</mapper>

SuccessKillDao.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.SuccessKillDao"> <!--主键重复时不再插入数据-->
<insert id="insertSuccessKilled"> insert ignore into success_killed (seckill_id,user_Phone,state) values (#{seckillId},#{userPhone},0)
</insert> <select id="queryByIdWithSeckill" resultType="SuccessKilled">
select
sk.seckill_id,
sk.user_Phone,
sk.state,
sk.create_time,
s.seckill_id "seckill.seckill_id",
s.name "seckill.name",
s.number "seckill.number",
s.create_time "seckill.create_time",
s.start_time "seckill.start_time",
s.end_time "seckill.end_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>

3、OK,准备工作就绪,可以实现单元测试的方法了。

 

基于SpringMVC+Spring+MyBatis实现秒杀系统【数据库接口】的更多相关文章

  1. 基于SpringMVC+Spring+MyBatis实现秒杀系统【概况】

    前言 本教程使用SpringMVC+Spring+MyBatis+MySQL实现一个秒杀系统.教程素材来自慕课网视频教程[https://www.imooc.com/learn/631].有感兴趣的可 ...

  2. 基于SpringMVC+Spring+MyBatis实现秒杀系统【客户端交互】

    前言 该篇主要实现客户端和服务的交互.在第一篇概况里我已经贴出了业务场景的交互图片. 客户端交互主要放在seckill.js里来实现.页面展现基于jsp+jstl来实现. 准备工作 1.配置web.x ...

  3. 基于SpringMVC+Spring+MyBatis实现秒杀系统【业务逻辑】

    前言 该篇主要实现秒杀业务层,秒杀业务逻辑里主要包括暴露秒杀接口地址.实现秒杀业务逻辑.同时声明了三个业务类:Exposer.SeckillExecution.SeckillResult. Expos ...

  4. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  5. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十二天】(系统架构讲解、nginx)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  6. 第04项目:淘淘商城(SpringMVC+Spring+Mybatis)【第十天】(单点登录系统实现)

    https://pan.baidu.com/s/1bptYGAb#list/path=%2F&parentPath=%2Fsharelink389619878-229862621083040 ...

  7. Idea SpringMVC+Spring+MyBatis+Maven调整【转】

    Idea SpringMVC+Spring+MyBatis+Maven整合   创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...

  8. SpringMVC+Spring+MyBatis+Maven调整【转】

    Idea SpringMVC+Spring+MyBatis+Maven整合   创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetyp ...

  9. SpringMVC+Spring+MyBatis个人技术博客源码

    项目描述 Hi,大家好,又到了源码分享时间啦,今天我们分享的源码一个<个人技术博客>,该博客是基于SSM实现的一个个人博客系统,适合初学SSM和个人博客制作的同学学习.有了这个源码,直接买 ...

随机推荐

  1. Forward团队-爬虫豆瓣top250项目-项目总结

    托管平台地址:https://github.com/xyhcq/top250 小组名称:Forward团队 组长:马壮 成员:李志宇.刘子轩.年光宇.邢云淇.张良 我们这次团队项目内容是爬取豆瓣电影T ...

  2. influence maximization 第二弹

    Robust Influence Maximization 首先简要介绍一下这个问题:在一个社交网络图中寻找固定数量的节点,使得这些节点对所有节点的影响值尽可能的大.先对这个问题给出形式化的定义:给一 ...

  3. VS2017 处理 Rdlc , microsoft report viewer 轻量级报表处理(WPF CS客户端版本)

    VS 2017没有安装处理Rdlc的包,需要手动安装: 点击主菜单中Tools 下拉菜单中 扩展和升级: 点选左侧Online  ,然后在右侧输入rdlc进行查询,然后 Download 下载安装 M ...

  4. C# WebAPI系列(2)

    上篇中简单介绍了一下WebApi,本章主要介绍一下Controller相关的知识. 在实际应用中,Controller是WebAPI的链接服务器和客户端的窗口.Controller的好坏影响整个系统的 ...

  5. ubuntu下file_get_contents返回空字符串

    ubuntu下file_get_contents返回空字符串 | 浏览:302 | 更新:2014-03-30 10:11 本文起初面临的问题是PHP中SoapClient不好使,最后file_get ...

  6. CLion之C++框架篇-优化开源框架,引入curl,实现get方式获取资源(四)

      背景   结合上一篇CLion之C++框架篇-优化框架,引入boost(三),继续进行框架优化!在项目中,我们经常会通过get方式拉取第三方资源,这一版优化引入类库curl,用来拉取第三方资源库. ...

  7. pwn入门之栈溢出练习

    本文原创作者:W1ngs,本文属i春秋原创奖励计划,未经许可禁止转载!前言:最近在入门pwn的栈溢出,做了一下jarvisoj里的一些ctf pwn题,感觉质量都很不错,难度循序渐进,把自己做题的思路 ...

  8. itemKNN发展史----推荐系统的三篇重要的论文解读

    itemKNN发展史----推荐系统的三篇重要的论文解读 本文用到的符号标识 1.Item-based CF 基本过程: 计算相似度矩阵 Cosine相似度 皮尔逊相似系数 参数聚合进行推荐 根据用户 ...

  9. pycharm删除project

    1 在pycharm里面选择关闭project 2 返回到这个页面,然后点×让project不在project列表显示(最好记住project的位置) 3 到源文件夹删除这个project文件夹 大功 ...

  10. Python-OpenCV 图像叠加加权实现

    函数说明 cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst 1 参数说明 src1 – first input ...