4.28 使用Maven搭建SSM项目(一)--秒杀系统api之DAO层

来源:互联网 发布:spyder导入tensorflow 编辑:程序博客网 时间:2024/05/22 11:59

之前记录了自己第一次手动搭建SSM框架的过程,在写的过程中都是想到什么记的什么,思路比较混乱,项目的结构也不严谨。
今天通过学习一个SSM小项目来学习使用Maven搭建。
项目为慕课网上 搞定Java SSM框架开发的综合案例–实现一个秒杀系统案例。

1.首先搭建项目
使用Maven构建来管理依赖项,pom.xml文件:
此pom.xml可作为大多数ssm项目依赖的参考

<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>maven_demo</groupId>  <artifactId>seckill</artifactId>  <packaging>war</packaging>  <version>1.0-SNAPSHOT</version>  <name>seckill Maven Webapp</name>  <url>http://maven.apache.org</url>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.11</version>    </dependency>    <!-- 1.日志包-->    <dependency>      <groupId>org.slf4j</groupId>      <artifactId>slf4j-api</artifactId>      <version>1.7.20</version>    </dependency>    <dependency>      <groupId>ch.qos.logback</groupId>      <artifactId>logback-core</artifactId>      <version>1.1.7</version>    </dependency>    <!--实现sl4j并整合 -->    <dependency>      <groupId>ch.qos.logback</groupId>      <artifactId>logback-classic</artifactId>      <version>1.1.7</version>    </dependency>    <!--2.数据库 -->    <dependency>      <groupId>mysql</groupId>      <artifactId>mysql-connector-java</artifactId>      <version>5.1.39</version>      <scope>runtime</scope>    </dependency>    <dependency>      <groupId>c3p0</groupId>      <artifactId>c3p0</artifactId>      <version>0.9.1.2</version>    </dependency>    <!-- dao框架依赖-->    <dependency>      <groupId>org.mybatis</groupId>      <artifactId>mybatis</artifactId>      <version>3.4.2</version>    </dependency>    <dependency>      <groupId>org.mybatis</groupId>      <artifactId>mybatis-spring</artifactId>      <version>1.3.1</version>    </dependency>    <!-- 3.servlet相关-->    <dependency>      <groupId>taglibs</groupId>      <artifactId>standard</artifactId>      <version>1.1.2</version>    </dependency>    <dependency>      <groupId>jstl</groupId>      <artifactId>jstl</artifactId>      <version>1.2</version>    </dependency>    <dependency>      <groupId>com.fasterxml.jackson.core</groupId>      <artifactId>jackson-databind</artifactId>      <version>2.5.4</version>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>    </dependency>    <!--todo 4.spring依赖 -->    <!--todo 1) spring core-->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <!--todo 2) spring dao层-->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-jdbc</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-tx</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <!--todo 3) web相关依赖 -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>    <!--todo 4)spring test 相关-->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-test</artifactId>      <version>4.1.7.RELEASE</version>    </dependency>  </dependencies>  <build>    <finalName>seckill</finalName>  </build></project>

依赖图:
这里写图片描述

2.使用IDEA构建好项目之后,并不是完全规范的maven项目,需要添加几个文件夹,使项目结构规范:
这里写图片描述

资源文件下分类:
这里写图片描述

  • mapper文件夹:存放mybatis映射文件
  • spring文件夹:spring/springmvc配置文件
  • sql文件夹:sql脚本
  • 其他日志文件,mybatis全局配置,数据库配置

3.spring和mybatis整合配置:spring-dao.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">    <!--todo mybatis整合 -->    <!--todo 1.配置数据库相关配置 -->    <bean id="propertyConfigurer"          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">        <property name="location" value="classpath:jdbc.properties" />    </bean>    <!--todo 2.数据库连接池-->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${driver}"/>        <property name="jdbcUrl" value="${url}"/>        <property name="user" value="${username}"/>        <property name="password" value="${password}"/>        <!-- 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>    <!--todo 3.配置sqlSessionFactory对象-->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <property name="dataSource" ref="dataSource"/>        <property name="configLocation" value="classpath:mybatis-config.xml"/>        <!--扫描包,使用别名 -->        <property name="typeAliasesPackage" value="org.seckill.entity"/>        <property name="mapperLocations" value="classpath:mapper/*.xml"/>    </bean>    <!--todo 4.配置扫描Dao接口包,实现Dao接口,注入spring容器-->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <!--注入sqlSessionFactory-->        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>        <!--扫描Dao接口包-->        <property name="basePackage" value="org.seckill.dao"/>    </bean></beans>

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>    <!--todo 配置全局属性 -->    <settings>        <!--todo 使用jdbc的getGeneratedKeys 获取数据库自增主键值-->        <setting name="useGeneratedKeys" value="true"/>        <!-- 使用列别名替换为 默认:true-->        <setting name="useColumnLabel" value="true"/>        <!-- 开启驼峰命名转换:Table(create time)-> Entity(createTime)-->        <setting name="mapUnderscoreToCamelCase" value="true"/>    </settings></configuration>

logback.xml

<?xml version="1.0" encoding="UTF-8"?><configuration>    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder            by default -->        <encoder>            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n            </pattern>        </encoder>    </appender>    <root level="debug">        <appender-ref ref="STDOUT" />    </root></configuration>

数据库脚本

-- 数据库初始化脚本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元秒杀iphone',100,'2017-04-01 00:00:00','2017-04-02 00:00:00'),  ('500元秒杀ipad2',100,'2017-04-01 00:00:00','2017-04-02 00:00:00'),  ('300元秒杀小米4',100,'2017-04-01 00:00:00','2017-04-02 00:00:00'),  ('100元秒杀红米note',100,'2017-04-01 00:00:00','2017-04-02 00:00:00');-- 秒杀成功明细表-- 用户登录认证相关信息CREATE TABLE success_killed (  `seckill_id` BIGINT NOT NULL,  `user_phone` BIGINT NOT NULL ,  `state` TINYINT NOT NULL DEFAULT -1,  `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,  PRIMARY KEY (seckill_id,user_phone),/*联合主键*/  KEY idx_create_time(create_time))ENGINE =InnoDB DEFAULT CHARSET =utf8 COMMENT ='秒杀成功明细表';

4.数据库创建好之后,编写对应实体对象和DAO层接口,
实体对象省略,下面时DAO接口
SeckillDao.java

package org.seckill.dao;import org.apache.ibatis.annotations.Param;import org.seckill.entity.Seckill;import java.util.Date;import java.util.List;/** * Created by kay on 2017/4/28. */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(long seckillId);    /**     * 根据偏移量查询秒杀商品列表     * @param offset     * @param limit     * @return     */    List<Seckill> queryAll(@Param("offset") int offset,@Param("limit") int limit);}

SuccessKilledDao.java

package org.seckill.dao;import org.apache.ibatis.annotations.Param;import org.seckill.entity.SuccessKilled;/** * Created by kay on 2017/4/28. */public interface SuccessKilledDao {    /**     * 插入购买明细,可过滤重复     * @param seckillId     * @param userPhone     * @return     */    int insertSuccessKilled(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);    /**     *     * @param seckillId     * @return     */    SuccessKilled queryByIdWithSeckill(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);}

5.编写mapper映射文件

1)SeckillDao.xml
<!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="org.seckill.dao.SeckillDao">    <update id="reduceNumber">        UPDATE          seckill        SET number=number-1        WHERE seckill_id=#{seckillId}    <!--todo <![CDATA[]]> 避免 =为xml不兼容-->        AND start_time <![CDATA[<=]]>#{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        LIMIT #{offset},#{limit}    </select></mapper>
2)SuccessSeckilledDao.xml
<!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="org.seckill.dao.SuccessKilledDao">    <insert id="insertSuccessKilled">        <!--todo 当主键冲突时忽略报错 -->        INSERT IGNORE INTO success_killed(seckill_id,user_phone)                VALUES (#{seckillId},#{userPhone})    </insert>    <select id="queryByIdWithSeckill" resultType="SuccessKilled">        <!--todo 告诉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}    </select></mapper>

6.测试一下DAO接口

import org.junit.Test;import org.junit.runner.RunWith;import org.seckill.dao.SeckillDao;import org.seckill.entity.Seckill;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.annotation.Resource;import java.util.Date;import java.util.List;/** * Created by kay on 2017/4/28. * 配置spring和junit的整合,junit启动时要加载springIOC容器 * spring-test,junit */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration({"classpath:spring/spring-dao.xml"})public class SeckillDaoTest {    @Resource    private SeckillDao seckillDao;    @Test    public void queryById() throws Exception {        long id=1000;        Seckill seckill =seckillDao.queryById(id);        System.out.println(seckill.getName());        System.out.println(seckill);    }    /**     * Caused by: org.apache.ibatis.binding.BindingException: Parameter 'offset' not found.     * Available parameters are [arg1, arg0, param1, param2]     * @throws Exception     * java没有保存形参的记录,多个参数要告诉Mybatis每个位置的参数叫什么     */    @Test    public void queryAll() throws Exception {       List<Seckill> seckillList =seckillDao.queryAll(0,100);       for (Seckill seckill:seckillList){           System.out.println(seckill);       }    }    @Test    public void reduceNumber() throws Exception {        Date killTime=new Date();        int reduceNumber=seckillDao.reduceNumber(1000L,killTime);        System.out.println(reduceNumber);    }}

DAO层设计与编写就到这里——4.28

0 0
原创粉丝点击