[SSM project: Java high concurrency spike API] 1 business analysis and DAO layer

1. Project overview



1.1 SSM framework advantages

  • The framework is easy to use and lightweight
  • Low code intrusion
  • Mature community and user base

1.2 introduction to relevant technologies

1.MySQL

  • Table design
  • SQL skills
  • Transaction and row level locks

2.MyBatis

  • Design and development of DAO layer
  • MyBatis rational use
  • MyBatis and Spring integration

3.Spring

  • Spring IOC integration Service
  • Declarative transaction application

4.SpringMVC

  • Restful interface design and use
  • Framework operation process
  • Controller development skills

5. Front end

  • Interaction design
  • Bootstrap
  • jQuery

6. High concurrency

  • High concurrency point and high concurrency analysis
  • Optimize ideas and implement

1.3 second kill business analysis

1.3. 1. Business process of second kill system

1.3. 2. The core of second kill business: inventory processing


1.3. 3 why transactions are needed

1.3. 4. Data landing

MySQL VS NoSQL

NoSQL: the transaction support is not very good, and the pursuit is performance, high availability and distributed
MySQL: the built-in transaction mechanism is still the most effective and reliable data landing scheme at present - > inventory reduction and purchase behavior can be recorded more reliably

1.4 difficulty analysis of MySQL second kill

Difficult problem: Competition - > transaction + row level lock

Transaction working mechanism:

  • Start Transaction
  • Update inventory quantity - > competition appears here
  • Insert purchase details
  • Commit

Row level lock - > with competition

How to deal with competition efficiently: high concurrency

1.5 what second kill functions can be realized

  • Second kill interface exposure
  • Execute second kill
  • Related query: List query and detail page query

Code development phase

  • DAO design coding: database table design, Dao interface, and how MyBatis implements Dao
  • Service design code:
    Service interface design and coding implementation, managing services through Spring, and labeling services through Spring declarative transactions. The method is a transaction operation to simplify transaction control
  • Web design coding: Restful interface, front-end interaction

2. Create projects and dependencies

2.1 description before creation

  • Create from scratch

  • Obtain relevant configurations from the official website
    1. More comprehensive and authoritative documents
    2. Avoid obsolescence or errors

  • Create a project using Maven

2.2 start creating project

  1. New Maven project

    Maven installation and its configuration and use in IDEA (nanny tutorial)

  2. New Web project

    Java learning [framework (III)] spring MVC (I) review MVC Architecture & Servlet

The results are as follows:

2.3 import dependency

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.seckill</groupId>
    <artifactId>seckill</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <!-- use junit4(3.0 Programming mode is used by default, 4.0 Run in annotation mode later junit)-->
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!-- Complete project dependency -->

        <!-- 1:journal java journal: slf4j, log4j, logback, common-logging
             slf4j Is the norm/Interface
             Log implementation: log4j, logback, common-logging
             use: slf4j + logback
        -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.1</version>
        </dependency>
        <!-- realization slf4j Interface and integration -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!-- 2. Database dependency -->
        <!-- mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
            <scope>runtime</scope>
        </dependency>
        <!-- Database connection pool-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>

        <!-- 3. DAO Frame: MyBatis rely on -->
        <!-- MyBatis Self dependence -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.3.0</version>
        </dependency>
        <!-- MyBatis Self implemented Spring Integration dependence -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.3</version>
        </dependency>

        <!-- 3. Servlet web Correlation dependency -->
        <!-- jsp Corresponding label -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!-- js Default label Library -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- SpringMVC Default needs jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.4</version>
        </dependency>
        <!-- servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <!-- 4. Spring rely on-->
        <!-- 1)Spring Core dependency-->
        <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>
        <!-- 2) Spring DAO Layer dependence -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!-- Spring Transaction dependency -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!-- 3) Spring web Correlation dependency-->
        <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>
        <!-- 4) Spring test Related dependencies (for unit testing) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>

    </dependencies>
</project>

3. Database design code

Java learning [framework (II)] MyBatis (I) the first MyBatis query program

  1. Create a new schema under main sql
    (I connected to the database, but I didn't connect to MyBatis - > crazy MyBatis was configured in the resource. As of this step, I haven't configured it yet)

schema. The SQL statements in SQL are as follows:

-- Database initialization script

-- Create database
CREATE  DATABASE `seckill`;
-- Use database
use `seckill`;
-- Create a second kill inventory table
CREATE TABLE `seckill`(
`seckill_id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Commodity inventory id',
`name` varchar(120) NOT NULL COMMENT 'Trade name',
`number` int NOT NULL COMMENT 'Inventory quantity',
`start_time` datetime NOT NULL COMMENT 'Spike start time',
`end_time` datetime NOT NULL COMMENT 'Spike end time',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation time',
-- Design index
-- idx by index abbreviation
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 'Second kill inventory Watch';
-- Initialization data
insert into
    `seckill`(`name`, `number`, `start_time`, `end_time`)
values
    ('1000 Yuan second kill iphone6',  100, '2015-11-01 00:00:00', '2015-11-02 00:00:00'),
    ('500 Yuan second kill ipad2',  200, '2015-11-01 00:00:00', '2015-11-02 00:00:00'),
    ('300 Yuan spike millet 4',  300, '2015-11-01 00:00:00', '2015-11-02 00:00:00'),
    ('200 Yuan second kill red rice note',  400, '2015-11-01 00:00:00', '2015-11-02 00:00:00');
-- Second kill success details
-- Information related to user login authentication
create table `success_killed`(
`seckill_id` bigint NOT NULL COMMENT 'Second kill commodity id',
`user_phone` bigint NOT NULL COMMENT 'User mobile number',
`state` tinyint NOT NULL DEFAULT -1 COMMENT 'Status identification: -1: Invalid 0: Success 1: Paid 2: Shipped',
`create_time` datetime NOT NULL COMMENT 'Creation time',
PRIMARY KEY (`seckill_id`, `user_phone`),  -- composite keys 
key idx_create_time(create_time)
)ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT 'Second kill success details';

Modify database field properties:

ALTER TABLE `success_killed` MODIFY `create_time` datetime;

Show how tables are created:

show CREATE TABLE `success_killed`;
CREATE TABLE `success_killed` (
  `seckill_id` bigint(20) NOT NULL COMMENT 'Second kill commodity id',
  `user_phone` bigint(20) NOT NULL COMMENT 'User mobile number',
  `state` tinyint(4) NOT NULL DEFAULT '-1' COMMENT 'Status identification: -1: Invalid 0: Success 1: Paid 2: Shipped',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`seckill_id`,`user_phone`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Second kill success details'

The results are as follows:

4. DAO layer entity and interface coding

Correspondence between label and entity

  • The table corresponds to the entity class in Java
  • Column corresponds to the attribute in the entity

Create entity package & Dao layer package
org.seckill.entity
org.seckill.dao

4.1 writing entity classes

4.1.1 Seckill entity class

package org.seckill.entity;

import java.util.Date;

public class Seckill {
    private long seckillId;
    private String name;
    private int number;
    private Date startTime;
    private Date endTime;
    private Date createTime;

    // Alt + insert
    public long getSeckillId() {
        return seckillId;
    }

    public void setSeckillId(long seckillId) {
        this.seckillId = seckillId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Seckill{" +
                "seckillId=" + seckillId +
                ", name='" + name + '\'' +
                ", number=" + number +
                ", startTime=" + startTime +
                ", endTime=" + endTime +
                ", createTime=" + createTime +
                '}';
    }
}

4.1. 2 class successkilled

package org.seckill.entity;

import java.util.Date;

public class SuccessKilled {
    private long skillId;
    private long userPhone;
    private short state;
    private Date createTime;

    // Flexible
    // Many to one (composite attribute): one Seckill entity corresponds to multiple successful Seckill records
    private Seckill seckill;

    public long getSkillId() {
        return skillId;
    }

    public void setSkillId(long skillId) {
        this.skillId = skillId;
    }

    public long getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(long userPhone) {
        this.userPhone = userPhone;
    }

    public short getState() {
        return state;
    }

    public void setState(short state) {
        this.state = state;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Seckill getSeckill() {
        return seckill;
    }

    public void setSeckill(Seckill seckill) {
        this.seckill = seckill;
    }

    @Override
    public String toString() {
        return "SuccessKilled{" +
                "skillId=" + skillId +
                ", userPhone=" + userPhone +
                ", state=" + state +
                ", createTime=" + createTime +
                '}';
    }
}

4.2 design DAO interface

4.2.1 SeckillDao interface

Naming convention: corresponding entity + Dao - > e.g. SeckillDao

package org.seckill.dao;

import org.seckill.entity.Seckill;

import java.util.Date;
import java.util.List;

public interface SeckillDao {

    // Inventory reduction (killTime the time when inventory reduction is performed corresponds to the createtime in the database)
    // If the number of affected rows > 1, it indicates the number of updated record rows
    int reduceNumber(long seckillId, Date killTime);

    // Query requirements (query the second kill object according to id)
    Seckill queryById(long seckillId);

    // Query the second kill product list according to the offset
    // Offset: offset, limit: how many records are taken after the offset
    List<Seckill> queryAll(int offet, int limit);
}

4.2. 2 successkilledao interface

package org.seckill.dao;

import org.seckill.entity.SuccessKilled;

public interface SuccessKilledDao {

    // Insert purchase details to filter duplicates (joint unique primary key)
    // Number of rows inserted
    int insertSuccessKilled(long seckillId, long userPhone);

    // Query SuccessKilled by id and carry the second kill product object entity
    SuccessKilled queryByIdWithSeckill(long seckillId);
}

Keywords: Java MySQL Mybatis Spring Back-end

Added by carobee on Thu, 16 Dec 2021 18:40:31 +0200