Java秒杀系统实践学习

Java秒杀系统实践学习

前言

java秒杀系统核心设计到分布式系统方案、系统的极致优化、深入微服务技能、安全策略,希望通过对他的学习能过对他所涉及到的springboot框架体系结构、redis缓存、mybatis等有进一步了解和认知。

项目框架的搭建

项目框架的搭建分为四部分:

一、 Spring Boot的环境搭建;

通过idea创建springboot项目,点击File再点击project然后选择Spring initializr,勾选mybatis、redis、Mysql、Thymaleaf的依赖,创建springboot的项目

二、 集成Thymeleaf,Result结果封装;

thymeleaf模板引擎是用来替代jsp,默认页面跳转默认路径:src/main/resources/templates,静态资源默认路径:src/main/resources/static.

使用Thymeleaf的依赖,如下所示:

<dependency>
	 <groupId>org.springframework.boot</groupId> 
 	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

在配置文件中application.properties添加以下配置信息

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.enabled=true
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode= HTML5

其中主要的是spring.thymeleaf.prefix=classpath:/templates/(路径)和spring.thymeleaf.suffix=.html(文件后缀)两条配置信息,有了之后在Controller中返回的字符串会到resources/templates下对对应文件进行映射

在写controller里映射,就可以让其映射到resources/templates下文件hello.html文件

在这里插入图片描述

Result结果封装是因为在处理数据后都会返回一个数据值,为方便对返回结果的统一处理而创建的;主要包含两部分,在CodeMsg类中封装状态码和状态信息,也就是状态码(code)、状态信息(msg)变量,然后进一步封装一个CodeMsg类型的静态变量来使用,在Result类中封装信息处理的返回数据,因为具体数据的类型不确定,所以结果类是一个泛型类(Result)

定义各种状态码和信息:

public class CodeMsg {
    private int code;
    private String msg;

    public static CodeMsg SUCCESS = new CodeMsg(0, "success");
    public static CodeMsg  ERROR = new CodeMsg(500, "服务端异常");

    private CodeMsg(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}

数据处理返回:

public class Result<T> {
    private int code;
    private String msg;
    private T data;

    /**
     * 成功时候的调用
     * */
    public static <T> Result<T> success(T data){
        return new  Result<T>(data);
    }

    /**
     * 失败时候的调用
     * */
    public static <T> Result<T> error(CodeMsg cm){
        return new  Result<T>(cm);
    }

    /**
     * 成功时只设置消息
     * */
    private Result(T data) {
        this.code = 0;
        this.msg = "success";
        this.data = data;
    }

    /**
     * 将返回消息CodeMsg封装到本类中
     * */
    private Result(CodeMsg cm) {
        if(cm == null) {
            return;
        }
        this.code = cm.getCode();
        this.msg = cm.getMsg();
    }

    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
    public T getData() {
        return data;
    }
}

三、集成Mybatis+Druid;

使用的依赖信息如下::

		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.5</version>
        </dependency>

在配置文件中application.properties添加配置数据库连接信息,使用Mybatis注解方式,直接在dao层接口方法上使用mybatis依赖下的注解(连接数据进行测试可能报Error:testWhileIdle is true, validationQuery not set是由于mysql依赖版本引起的,不影响运行)

#mybatis
mybatis.type-aliases-package=com.example.demo.domain
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-fetch-size=100
mybatis.configuration.default-statement-timeout=3000
mybatis.mapper-locations=classpath:com/example/demo/dao/*.xml

#druid
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/miaosha?useSSL=false&serverTimezone=UTC&autoReconnect=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.filters= stat
spring.datasource.maxActive=2
spring.datasource.initialSize= 1
spring.datasource.maxWait= 60000
spring.datasource.minldle= 1
spring.datasource.timeBetweenEvictionRunsMillis= 60000
spring.datasource.minEvictableldleTimeMillis= 300000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileldle= true
spring.datasource.testOnBorrow= false
spring.datasource.testOnReturn= false
spring.datasource.poolPreparedStatements =true
spring.datasource.maxOpenPreparedStatements=20

创建数据库和表,写一个用测试数据连接的方法,将结果用Result封装返回:

Controller:
@RequestMapping("/db/get")
    @ResponseBody
    public Result<User> dbGet (){
        User user=userService.getuserByid(1);
        return Result.success(user);
    }
  Service:
  @Autowired
    UserDao userDao;
    public User getuserByid(int id){
        return  userDao.userByid(id);
    }
  dao:
  @Select("select * from user where id=#{id}")
    public User userByid(@Param("id") int id);

测试结果:在这里插入图片描述

四、集成Jedis+Redis的安装+通用缓存Key封装;

Windows下的Redis安装直接使用,修改Redis服务的密码可以在redis.windows.conf或redis.windows-service.conf中修改 requirepass 后面的参数即可,如下所示:
在这里插入图片描述
在cmd中进入redis的解压目录,输入redis-server.exe redis.windows.conf可以启动redis.

Reddis简介:Redis是一个速度非常快的非关系数据库(non-relational database),它可以存储键(key)与5种不同类型的值(value)之间的映射(mapping),可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展写性能。
Redis与其他数据库及软件之间的区别:

在这里插入图片描述
SpringBoot整合Redis的方法:
1、Jedis (具体分为:添加依赖+redis配置信息+JedisPool工厂+RedisService)
2、RedisTemplate(具体分为:添加依赖+redis配置信息+RedisTemplate+序列化+RedisService)

SpringBoot使用Jedis整合Redis:

思路:在RedisConfig里接收配置文件里参数信息,在RedisPoolFactory中用@Bean将JedisPool注入Spring容器,在RedisService中实现Redis服务进行增删改查,通过KeyPrefix 区分模块,对key进行加工,避免团队开发时key被覆盖,采用方式是:接口->抽象类->实现类。

使用Fastjson原因是它可以让Java对象转换为json字符串写到redis的服务器中,序列化后是可读的,方便查看。

在pom.xml添加Jedis和Fastjson依赖信息如下:

 		<dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.38</version>
        </dependency>

Redis基本配置及工具类
1.创建redis.properties配置文件
注意max-active,max-wait,max-idle,min-idle这几个参数版本不同写法也不一样

#redis配置开始
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=1024
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=200
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=10000
#redis配置结束
spring.redis.block-when-exhausted=true

2.添加配置类RedisConfig.java接收配置文件的参数信息

package com.example.demo.redis;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "redis")
public class RedisConfig {
    private String host;
    private int port;
    private int timeout;
    private  String password;
    private  int poolMaxTotal;
    private  int poolMaxldle;
    private  int poolMaxWait;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPoolMaxTotal() {
        return poolMaxTotal;
    }

    public void setPoolMaxTotal(int poolMaxTotal) {
        this.poolMaxTotal = poolMaxTotal;
    }

    public int getPoolMaxldle() {
        return poolMaxldle;
    }

    public void setPoolMaxldle(int poolMaxldle) {
        this.poolMaxldle = poolMaxldle;
    }

    public int getPoolMaxWait() {
        return poolMaxWait;
    }

    public void setPoolMaxWait(int poolMaxWait) {
        this.poolMaxWait = poolMaxWait;
    }
}


3.添加RedisPoolFactory类,用@Bean将JedisPool连接池信息注入spring容器

package com.example.demo.redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Service
public class RedisPoolFactory {
    @Autowired
    RedisConfig redisConfig;

    @Bean
    public JedisPool JedisPoolFactory(){
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(redisConfig.getPoolMaxldle());
        poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
        poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait()* 1000);
        JedisPool jp = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),redisConfig.getTimeout()*1000
                ,redisConfig.getPassword(),0);
        return  jp;
    }

}

4、在RedisService中通过JedisPool创建jedis对象来实现redis的增删改查:

package com.example.demo.redis;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Service
public class RedisSevice {
    @Autowired
    JedisPool jedisPool;
/*获取当个对象*/
    public <T> T get(KeyPrefix prefix,String key,Class<T> clazz){

        Jedis jedis=null;
        try {
            jedis=jedisPool.getResource();
            //生成真正的key
            String realKey=prefix.getPrefix()+key;
            String str=jedis.get(realKey);
            T t=stringToBean(str,clazz);
            return t;
        }finally {
            returnToPool(jedis);
        }
    }
/*设置对象*/
    public <T> boolean set(KeyPrefix prefix,String key,T value){

        Jedis jedis=null;
        try {
            jedis=jedisPool.getResource();

            String str=stringToBean(value);
            if(str==null||str.length()<=0){
                return  false;
            }
            //
            String realKey=prefix.getPrefix()+key;
            int seconds=prefix.expireSecconds();
            if (seconds<=0){
                jedis.set(realKey,str);
            }else{
                jedis.setex(realKey,seconds,str);
            }

            return true;
        }finally {
            returnToPool(jedis);
        }
    }
    private <T>String stringToBean(T value){
        if(value==null){
            return  null;

        }
        Class<?> clazz=value.getClass();
        if(clazz==int.class||clazz==Integer.class){
            return " "+value;
        }else if(clazz==String.class){
            return (String)value;
        }else if(clazz==long.class||clazz==Long.class){
            return " "+value;
        }else{
            return JSON.toJSONString(value);
        }

    }
    private void returnToPool(Jedis jedis){
        if(jedis!=null){
            jedis.close();
        }
    }
    private <T> T stringToBean(String str,Class<T> clazz){
        if(str==null||str.length()<=0||clazz==null){
            return null;
        }
        if(clazz==int.class||clazz==Integer.class){
            return (T)Integer.valueOf(str);
        }else if(clazz==String.class){
            return (T)str;
        }else if(clazz==long.class||clazz==Long.class){
            return (T)Long.valueOf(str);
        }else{
            return JSON.toJavaObject(JSON.parseObject(str),clazz);
        }


    }
    /*判断key是否存在*/
    public <T> boolean exists(KeyPrefix prefix,String key){

        Jedis jedis=null;
        try {
            jedis=jedisPool.getResource();
            //生成真正的key
            String realKey=prefix.getPrefix()+key;
           return jedis.exists(realKey);

        }finally {
            returnToPool(jedis);
        }
    }
    public <T> Long incr(KeyPrefix prefix,String key){

        Jedis jedis=null;
        try {
            jedis=jedisPool.getResource();
            //生成真正的key
            String realKey=prefix.getPrefix()+key;
            return jedis.incr(realKey);

        }finally {
            returnToPool(jedis);
        }

    }
    public <T> Long decr(KeyPrefix prefix,String key){

        Jedis jedis=null;
        try {
            jedis=jedisPool.getResource();
            //生成真正的key
            String realKey=prefix.getPrefix()+key;
            return jedis.decr(realKey);

        }finally {
            returnToPool(jedis);
        }
    }


}

KeyPrefix 设计思路:接口——>抽象——>实现:
目的是在key前面加前缀,避免多人合作时key覆盖使用。
创建接口KeyPrefix :

package com.example.demo.redis;

public interface KeyPrefix {
    public int expireSecconds();//有效期
    public String getPrefix();//前缀
}

创建抽象类BasePrefix:

package com.example.demo.redis;

public abstract class BasePrefix implements KeyPrefix{

    private  int expireSeconds;
    private  String prefix;
    public BasePrefix(String prefix) {//0代表永不过期
        this(0,prefix);
    }

    public BasePrefix(int expireSeconds, String prefix) {
        this.expireSeconds = expireSeconds;
        this.prefix = prefix;
    }



    @Override
    public int expireSecconds() {
        return expireSeconds;
    }

    @Override
    public String getPrefix() {
        String className=getClass().getSimpleName();
        return className+":"+prefix;
    }
}

实现Userkey:

package com.example.demo.redis;

public class UserKey extends BasePrefix {

    private UserKey( String prefix) {
        super(prefix);
    }

    public static  UserKey getById =new UserKey("id");
    public static  UserKey getByName =new UserKey("name");



}

SpringBoot使用RedisTemplate整合Redis:

添加依赖:

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>${redis.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>${spring.redis.version}</version>
</dependency>

redis的配置文件:

#redis配置开始
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=1024
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=200
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=10000
#redis配置结束
spring.redis.block-when-exhausted=true

RedisTemplate:

@Configuration
@PropertySource("classpath:redis.properties")
@Slf4j
public class RedisConfig {
 
    @Value("${redis.hostName}")
    private String hostName;
 
    @Value("${redis.password}")
    private String password;
 
    @Value("${redis.port}")
    private Integer port;
 
    @Value("${redis.maxIdle}")
    private Integer maxIdle;
 
    @Value("${redis.timeout}")
    private Integer timeout;
 
    @Value("${redis.maxTotal}")
    private Integer maxTotal;
 
    @Value("${redis.maxWaitMillis}")
    private Integer maxWaitMillis;
 
    @Value("${redis.minEvictableIdleTimeMillis}")
    private Integer minEvictableIdleTimeMillis;
 
    @Value("${redis.numTestsPerEvictionRun}")
    private Integer numTestsPerEvictionRun;
 
    @Value("${redis.timeBetweenEvictionRunsMillis}")
    private long timeBetweenEvictionRunsMillis;
 
    @Value("${redis.testOnBorrow}")
    private boolean testOnBorrow;
 
    @Value("${redis.testWhileIdle}")
    private boolean testWhileIdle;
 
    /**
     * @auther: zhangyingqi
     * @date: 17:52 2018/8/28
     * @param: []
     * @return: org.springframework.data.redis.connection.jedis.JedisConnectionFactory
     * @Description: Jedis配置
     */
    @Bean
    public JedisConnectionFactory JedisConnectionFactory(){
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration ();
        redisStandaloneConfiguration.setHostName(hostName);
        redisStandaloneConfiguration.setPort(port);
        //由于我们使用了动态配置库,所以此处省略
        //redisStandaloneConfiguration.setDatabase(database);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
        jedisClientConfiguration.connectTimeout(Duration.ofMillis(timeout));
        JedisConnectionFactory factory = new JedisConnectionFactory(redisStandaloneConfiguration,
                jedisClientConfiguration.build());
        return factory;
    }
 
    /**
     * @auther: zhangyingqi
     * @date: 17:52 2018/8/28
     * @param: [redisConnectionFactory]
     * @return: com.springboot.demo.base.utils.RedisTemplate
     * @Description: 实例化 RedisTemplate 对象
     */
    @Bean
    public RedisTemplate functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        log.info("RedisTemplate实例化成功!");
        RedisTemplate redisTemplate = new RedisTemplate();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }
 
    /**
     * @auther: zhangyingqi
     * @date: 17:52 2018/8/28
     * @param: []
     * @return: org.springframework.data.redis.serializer.RedisSerializer
     * @Description: 引入自定义序列化
     */
    @Bean
    public RedisSerializer fastJson2JsonRedisSerializer() {
        return new FastJson2JsonRedisSerializer<Object>(Object.class);
    }
 
    /**
     * @auther: zhangyingqi
     * @date: 17:51 2018/8/28
     * @param: [redisTemplate, factory]
     * @return: void
     * @Description: 设置数据存入 redis 的序列化方式,并开启事务
     */
    private void initDomainRedisTemplate(RedisTemplate redisTemplate, RedisConnectionFactory factory) {
        //如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setValueSerializer(fastJson2JsonRedisSerializer());
        // 开启事务
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.setConnectionFactory(factory);
    }
 
    /**
     * @auther: zhangyingqi
     * @date: 17:51 2018/8/28
     * @param: [redisTemplate]
     * @return: com.springboot.demo.base.utils.RedisUtil
     * @Description: 注入封装RedisTemplate
     */
    @Bean(name = "redisUtil")
    public RedisUtil redisUtil(RedisTemplate redisTemplate) {
        log.info("RedisUtil注入成功!");
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        return redisUtil;
    }
 
}

使用FastJson来实现序列化 :

public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
 
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
 
    private Class<T> clazz;
 
    public FastJson2JsonRedisSerializer(Class<T> clazz) {
        super(); this.clazz = clazz;
    }
 
        @Override
        public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }
 
        @Override
        public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) JSON.parseObject(str, clazz);
    }
}

RedisService:

public String set(String key, String value,int indexdb) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			jedis.select(indexdb);
			return jedis.set(key, value);
		} catch (Exception e) {
 
			log.error(e.getMessage());
			return "0";
		} finally {
			returnResource(jedisPool, jedis);
		}
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
java实现秒杀系统@Controller @RequestMapping("seckill")//url:/模块/资源/{id}/细分 /seckill/list public class SeckillController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private SeckillService seckillService; @RequestMapping(value="/list",method = RequestMethod.GET) public String list(Model model){ //获取列表页 List list=seckillService.getSeckillList(); model.addAttribute("list",list); //list.jsp+model = ModelAndView return "list";//WEB-INF/jsp/"list".jsp } @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET) public String detail(@PathVariable("seckillId") Long seckillId, Model model){ if (seckillId == null){ return "redirect:/seckill/list"; } Seckill seckill = seckillService.getById(seckillId); if (seckill == null){ return "forward:/seckill/list"; } model.addAttribute("seckill",seckill); return "detail"; } //ajax json @RequestMapping(value = "/{seckillId}/exposer", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public SeckillResult exposer(@PathVariable("seckillId") Long seckillId){ SeckillResult result; try { Exposer exposer =seckillService.exportSeckillUrl(seckillId); result = new SeckillResult(true,exposer); } catch (Exception e) { logger.error(e.getMessage(),e); result = new SeckillResult(false,e.getMessage()); } return result; } @RequestMapping(value = "/{seckillId}/{md5}/execution", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"} ) @ResponseBody public SeckillResult execute(@PathVariable("seckillId")Long seckillId,
慕课网Java高并发秒杀(课程) 很好的spring,springMVC,mybatis,bootstrap,jQuery,mysql,Restful学习案例 SQL脚本 CREATE DATABASE seckill; USE seckill; -- todo:mysql Ver 5.7.12for Linux(x86_64)中一个表只能有一个TIMESTAMP 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` DATETIME 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 ('3000元秒杀iphone6',100,'2016-01-01 00:00:00','2016-12-31 00:00:00'), ('2000元秒杀ipad',100,'2016-01-01 00:00:00','2016-05-01 00:00:00'), ('6000元秒杀mac book pro',100,'2016-07-01 00:00:00','2016-12-31 00:00:00'), ('7000元秒杀iMac',100,'2016-05-01 00:00:00','2016-12-31 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='秒杀成功明细表' SHOW CREATE TABLE seckill\G;#显示表的创建信息 Mybatis两个问题?①sql写在哪里?②怎么实现DAO接口?第一个问题:注解或者XML选择XML.第二个问题:Mapper自动实现DAO接口或者API编程方式实现DAO接口.选择Mapper.

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值