idea+maven+ssm+redis+bootstarp实现简单的高并发秒杀API

涉及到的知识点
数据库
1.表设计
2.SQL技巧
3.事务和行级锁
MyBatis
1.DAO层设计与开发
2.MyBatis合理应用
3.MyBatis与Spring整合
Spring
1.Spring IOC整合Service
2.声明式事务
SpringMVC
1.Restful接口设计和使用
2.框架运作流程
3.Controller开发技巧
前端
1.交互设计
2.Bootstrap
3.jQuery
高并发
1.高并发点和高并发分析
2.优化思路并实现

一、创建数据库seckill
建议代码创建数据库、表
1.seckill
这里写图片描述
create_time取系统时间
这里写图片描述
2.success_killed
seckill_id与user_phone采用联合主键
这里写图片描述

二、maven项目搭建
1.下载idea
https://pan.baidu.com/s/1nu16VyD
安装idea非常简单,与其他开发工具配置类似
2.下载Maven
http://maven.apache.org/download.cgi
使用IntelliJ IDEA 配置Maven:
http://blog.csdn.net/qq_32588349/article/details/51461182
3.创建秒杀(seckill)项目
3.1:使用cmd命令创建maven项目

mvn archetype:generate -DgroupId=com.yuk.ssh -DartifactId=seckill -DarchetypeArtifactId=maven-archetype-webapp -DarchetypeCatalog=internal

进入项目文件夹
这里写图片描述
按回车键
提示:我在网上看到一次回车就可以成功,但是我在实际中按了3次回车,提示我是否按照默认配置。
这里写图片描述
3.2:手动创建
file->new project->maven…
这里写图片描述
提示:项目创建完成后,需要添加缺少的目录
使用快捷键 ctrl+alt+shift+s打开项目体系结构,或者点击右上角的这个图标
这里写图片描述
进行如下配置
这里写图片描述
这里写图片描述
至此,maven项目初步创建完毕

三、pom.xml文件配置
提示:我用的是sqlServer2014数据库,而sqljdbc是微软开发的,添加sqljdbc的maven依赖前需要将jar包安装到自己的私服上
下载sqljdbc.jar包之后可以通过下面的maven命令将jar包安装到自己的私服上

mvn install:install-file -Dfile=sqljdbc4.jar -Dpackaging=jar -DgroupId=com.microsoft.sqlserver -DartifactId=sqljdbc4 -Dversion=4.0

安装成功之后就可以在pom中引用sqljdbc依赖了
项目需要的依赖配置:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.yuk.ssh</groupId>
  <artifactId>seckill</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>seckill Maven Webapp</name>
  <url>http://maven.apache.org</url>


  <properties>
    <spring.version>4.2.5.RELEASE</spring.version>
    <slf4j.version>1.7.6</slf4j.version>
  </properties>

  <dependencies>

    <!--1.junit4.0版本以上可以使用注解:单元测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!--2.打印日志依赖包-->
    <dependency><!--是规范/接口-->
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>${slf4j.version}</version>
      <exclusions>
        <exclusion>
          <artifactId>slf4j-api</artifactId>
          <groupId>org.slf4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>

    <!--3.数据库相关依赖-->
    <dependency>
      <groupId>com.microsoft.sqlserver</groupId>
      <artifactId>sqljdbc4</artifactId>
      <version>4.0</version>
      <scope>runtime</scope>
    </dependency>
    <!--数据库连接池-->
    <dependency><!--优化数据库连接-->
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>

    <!--4..DAO框架:MyBatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.3.0</version>
    </dependency>
    <!--MyBatis自身实现的spring整合依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.3</version>
    </dependency>

    <!--5..Servlet web相关依赖-->
    <dependency><!--jstl需要的标签-->
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
    <dependency><!--jstl默认标签库-->
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency><!--json包-->
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.4</version>
    </dependency>
    <dependency><!--servlet包-->
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

    <!--6..spring依赖-->
    <!--spring核心依赖-->
    <dependency><!--核心-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency><!--IOC-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency><!--扫描-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--spring Dao层依赖-->
    <dependency><!--事务管理器-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency><!--spring声明式事务-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--spring web相关依赖-->
    <dependency><!--启动spring工厂-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--spring test相关依赖:单元测试加载spring容器-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--redis客户端:Jedis-->
    <dependency>
      <groupId>redis.clients</groupId>
      <artifactId>jedis</artifactId>
      <version>2.8.0</version>
    </dependency>

    <!--protostuff序列化依赖 -->
    <dependency>
      <groupId>com.dyuproject.protostuff</groupId>
      <artifactId>protostuff-core</artifactId>
      <version>1.0.8</version>
    </dependency>
    <dependency>
      <groupId>com.dyuproject.protostuff</groupId>
      <artifactId>protostuff-runtime</artifactId>
      <version>1.0.8</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>seckill</finalName>
  </build>
</project>

四、mybatis-Dao层
pom文件写完后,开始编写dao层代码
1.dao层理解
a.接口设计+SQL编写,
b.代码和SQL分离,方便Review,
c.dao层拼接等逻辑在Service层完成。
2.entity实体类
创建与数据库对应表的字段属性,采用驼峰命名法
这里写图片描述
Seckill.java:秒杀商品信息类
这里写图片描述
SuccessKilled.java:秒杀成功记录类
添加Seckill对象,方便实现多对一配置:秒杀成功时可显示秒杀商品的详细信息
这里写图片描述
3.dao层接口
SeckillDao.java
这里写图片描述
SuccessKilledDao.java
这里写图片描述
4.dao层接口实现
dao层是负责接口命名,具体的实现由mybatis完成
4.1在resources下新建mybatis-config.xml,mybatis核心文件

<?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 获取数据库自增长主键值 默认:false-->
        <setting name="useGeneratedKeys" value="true"/>

        <!--使用列名替换别名 默认:true-->
        <setting name="useColumnLabel" value="true"/>

        <!--开启驼峰命名转换:Table(create_time) -> Entity:(createTime)-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>


</configuration>

在resources下新建mapper
这里写图片描述
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="org.seckill.dao.SeckillDao">
    <!--为DAO接口提供sql语句配置-->
    <update id="reduceNumber">
        <!--具体的sql语句-->
        update seckill set number = number - 1
        where seckill_id = #{seckillId}
        and start_time &lt;= #{killTime}
        and end_time >= #{killTime}
        and number > 0
    </update>

    <select id="queryById" resultType="Seckill" parameterType="long">
      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 desc
    </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="org.seckill.dao.SuccessKilledDao">
        <update id="insertSuccessKilled">
          <!--主键冲突,报错-->
          insert into success_killed(seckill_id,user_phone)
          values(#{seckillId},#{userPhone})
        </update>
        
        <select id="queryByIdWithSeckill" resultType="SuccessKilled">
            <!--根据id查询并携带秒杀产品对象实体-->
                <!--如何告诉MyBatis把结果映射到SuccessKilled与Seckill-->

                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>

5.连接数据源及扫描等配置
resources下新建jdbc.properties文件,存储连接数据信息

jdbc.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=seckill
jdbc.username=sa
jdbc.password =123456

resources下新建spring-dao.xml,用于管理dao层

<?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">

    <!--配置整合MyBatis过程-->
    <!--1:配置数据库相关参数-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!--2:配置c3p0连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- ${key}可以读取properties文件中配置key对应的value -->
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <!--c3p0的私有属性-->
        <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="2"/>
    </bean>

    <!--3:配置SqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入数据库连接池-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置MyBatis全局配置文件:mybatis-config.xml-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--扫描entity包,使用别名:org.seckill.dao.Seckill -> Seckill-->
        <property name="typeAliasesPackage" value="org.seckill.entity"/>
        <!--扫描sql配置文件:mapper需要的xml文件-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!--4:配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory:为防止提前初始化sqlSessionFactory用BeanName-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--给出扫描Dao接口包-->
        <property name="basePackage" value="org.seckill.dao"/>
    </bean>

    <!--RedisDao-->
    <bean id="redisDao" class="org.seckill.dao.cache.RedisDao">
        <constructor-arg index="0" value="localhost"/>
        <constructor-arg index="1" value="6379"/>
    </bean>

</beans>

至此,dao层配置完成,可以通过单元测试一下sql语句正确性。在dao接口中右键
这里写图片描述
这里写图片描述
这里写图片描述
即可在test目录中生成对应的测试类
这里写图片描述
写好配置
这里写图片描述
选中方法名,右键
这里写图片描述
这里写图片描述
junit执行成功就显示绿色进度条
这里写图片描述

五、spring实现service层
service就是管理dao层,将dao层方法整合应用。
这里写图片描述
代码具体实现就不做详细描述。。来看看spring怎么与mybatis结合的
1.首先,spring肯定要扫描service层的类

<!--扫描service包下所有使用注解的类型-->
<context:component-scan base-package="org.seckill.service"/>

2.spring要使用事务
这里在service层类中用注解实现事务

<!--配置事务管理器-->
    <bean id="transactionMmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据库连接池-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--配置基于注解的声明式事务,优点:
        1.开发团队达成一致的约定,明确标注事务方法的编程风格
        2.保证事务方法的执行时间尽可能短,不要穿插其他网络操作RPC(缓存)/HTTP请求,或者剥离到事务方法外部
        3.不是所有的方法都需要事务,如只有一条修改操作、只读操作是不需要事务控制的
    -->
    <tx:annotation-driven transaction-manager="transactionMmanager"/>

提示:配置中的数据源dataSource从哪来的呢?其实获取的是上下文中的dataSource,也就是dao层配置文件中的dataSource。
在web.xml中初始化spring目录下所有的xml配置文件,service层xml配置就会找到dao层配置中的dataSource。
这里写图片描述
service配置完成,主要是在类中运用ioc与aop
@Autowired实现依赖注入
@Transactional实现事务控制,里面有参数可以设置隔离级别(ISOLATION)、传播特性(PROPAGATION)、只读(readOnly)、发生哪些异常事务回滚(-Exception)、发生哪些异常事务不回滚(+Exception)
这里写图片描述
这里写图片描述

五、spring-mvc实现web(controller)层
web层的配置文件

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:contenxt="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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--配置springMVC-->
    <!--1.开启springMVC注解模式-->
    <!--简化配置:
        (1).自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
        (2).提供一系列:数据绑定,数字和日期的format. @NumberFormat,@DateTimeFormat,xml与json默认读写支持
    -->
    <mvc:annotation-driven/>

    <!--servlet-mapping 映射路劲:"/",或导致静态资源找不到,例如:js,css,jsp等-->
    <!--2.静态资源默认servlet处理而不是DispatcherServlet:
        (1).加入对静态资源的处理
        (2).允许使用"/"做整体映射
    -->
    <mvc:default-servlet-handler/>

    <!--3.配置jsp 显示ViewResolver-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--扫描web相关的bean-->
    <contenxt:component-scan base-package="org.seckill.web"/>

</beans>

使用Restful交互设计
这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值