涉及到的知识点
数据库
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 <= #{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交互设计