Java秒杀功能-案例

数据库表设计

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `password` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `order_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `goods_id` bigint(20) NOT NULL,
  `goods_name` varchar(100) NOT NULL,
  `goods_count` int(11) NOT NULL DEFAULT '1',
  `goods_price` decimal(10,2) NOT NULL,
  `order_channel` int(11) NOT NULL DEFAULT '1',
  `status` int(11) NOT NULL DEFAULT '0',
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `seckill_order` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) NOT NULL,
  `goods_id` bigint(20) NOT NULL,
  `order_id` bigint(20) NOT NULL,
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_user_goods` (`user_id`,`goods_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

实体类

用户实体类
@Entity
@Table(name = "user")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private String password;

    // getters and setters
}

 商品实体类

@Entity
@Table(name = "goods")
public class Goods implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false)
    private BigDecimal price;

    @Column(nullable = false)
    private Integer stock;

    // getters and setters
}
秒杀商品实体类
@Entity
@Table(name = "seckill_goods")
public class SeckillGoods implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private Long goodsId;

    @Column(nullable = false)
    private BigDecimal seckillPrice;

    @Column(nullable = false)
    private Integer seckillStock;

    @Column(nullable = false)
    private Timestamp startTime;

    @Column(nullable = false)
    private Timestamp endTime;

    // getters and setters
}
秒杀订单实体类
@Entity
@Table(name = "seckill_order")
public class SeckillOrder implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private Long userId;

    @Column(nullable = false)
    private Long goodsId;

    @Column(nullable = false)
    private Long orderId;

    @Column(nullable = false)
    private Timestamp createTime;

    // getters and setters
}
订单实体类
@Entity
@Table(name = "order_info")
public class OrderInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private Long userId;

    @Column(nullable = false)
    private Long goodsId;

    @Column(nullable = false)
    private String goodsName;

    @Column(nullable = false)
    private Integer goodsCount;

    @Column(nullable = false)
    private BigDecimal goodsPrice;

    @Column(nullable = false)
    private Integer orderChannel;

    @Column(nullable = false)
    private Integer status;

    @Column(nullable = false)
    private Timestamp createTime;

    // getters and setters
}

数据访问层接口

用户数据访问层接口
public interface UserRepository extends JpaRepository {
    User findByName(String name);
}
商品数据访问层接口
public interface GoodsRepository extends JpaRepository {
}
秒杀商品数据访问层接口
public interface SeckillGoodsRepository extends JpaRepository {
    SeckillGoods findByGoodsId(Long goodsId);
}
秒杀订单数据访问层接口
public interface SeckillOrderRepository extends JpaRepository {
    SeckillOrder findByUserIdAndGoodsId(Long userId, Long goodsId);
}
订单数据访问层接口
public interface OrderInfoRepository extends JpaRepository {
}

服务实现

用户服务实现
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }

    public User getUserByName(String userName) {
        return userRepository.findByName(userName);
    }

    public User registerUser(User user) {
        return userRepository.save(user);
    }

    // 其他用户相关业务逻辑
}
商品服务实现
@Service
public class GoodsService {

    @Autowired
    private GoodsRepository goodsRepository;

    public Goods getGoodsById(Long goodsId) {
        return goodsRepository.findById(goodsId).orElse(null);
    }

    public List getAllGoods() {
        return goodsRepository.findAll();
    }

    // 其他商品相关业务逻辑
}
秒杀商品服务实现
@Service
public class SeckillGoodsService {

    @Autowired
    private SeckillGoodsRepository seckillGoodsRepository;

    public SeckillGoods getSeckillGoodsByGoodsId(Long goodsId) {
        return seckillGoodsRepository.findByGoodsId(goodsId);
    }

    public List getAllSeckillGoods() {
        return seckillGoodsRepository.findAll();
    }

    // 其他秒杀商品相关业务逻辑
}
秒杀订单服务实现
@Service
public class SeckillOrderService {

    @Autowired
    private SeckillOrderRepository seckillOrderRepository;

    public SeckillOrder getSeckillOrderByUserIdGoodsId(Long userId, Long goodsId) {
        return seckillOrderRepository.findByUserIdAndGoodsId(userId, goodsId);
    }

    public SeckillOrder createSeckillOrder(SeckillOrder seckillOrder) {
        return seckillOrderRepository.save(seckillOrder);
    }

    // 其他秒杀订单相关业务逻辑
}
订单服务实现
@Service
public class OrderInfoService {

    @Autowired
    private OrderInfoRepository orderInfoRepository;

    public OrderInfo createOrderInfo(OrderInfo orderInfo) {
        return orderInfoRepository.save(orderInfo);
    }

    public OrderInfo getOrderInfoById(Long orderId) {
        return orderInfoRepository.findById(orderId).orElse(null);
    }

    // 其他订单相关业务逻辑
}
秒杀服务实现
@Service
public class SeckillService {

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private SeckillGoodsService seckillGoodsService;
    @Autowired
    private SeckillOrderService seckillOrderService;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private RabbitMQSender rabbitMQSender;
    @Autowired
    private RedisService redisService;

    @Transactional(rollbackFor = Exception.class)
    public Result seckill(Long userId, Long goodsId) {
        // 查询商品信息
        Goods goods = goodsService.getGoodsById(goodsId);
        if (goods == null) {
            return Result.error("商品不存在");
        }
        // 查询秒杀商品信息
        SeckillGoods seckillGoods = seckillGoodsService.getSeckillGoodsByGoodsId(goodsId);
        if (seckillGoods == null) {
            return Result.error("秒杀商品不存在");
        }
        // 判断库存是否足够
        if (seckillGoods.getSeckillStock() <= 0) {
            return Result.error("库存不足");
        }
        // 检查用户是否已经秒杀过该商品
        SeckillOrder seckillOrder = seckillOrderService.getSeckillOrderByUserIdGoodsId(userId, goodsId);
        if (seckillOrder != null) {
            return Result.error("重复秒杀");
        }
        // 创建秒杀订单信息
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setGoodsId(goodsId);
        orderInfo.setGoodsName(goods.getName());
        orderInfo.setGoodsCount(1);
        orderInfo.setGoodsPrice(seckillGoods.getSeckillPrice());
        orderInfo.setOrderChannel(1);
        orderInfo.setStatus(0);
        orderInfo.setCreateTime(new Date());
        // 使用 RabbitMQ 异步创建订单
        rabbitMQSender.sendOrderInfo(orderInfo);
        return Result.success(orderInfo);
    }

    public Result getResult(Long userId, Long goodsId) {
        SeckillOrder seckillOrder = seckillOrderService.getSeckillOrderByUserIdGoodsId(userId, goodsId);
        if (seckillOrder != null) {
            return Result.success(seckillOrder);
        } else {
            return Result.error("未抢到");
        }
    }
}
Redis 服务实现
@Service
public class RedisService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public void cacheGoodsStock(List goodsList) {
        if (goodsList == null) {
            return;
        }
        for (Goods goods : goodsList) {
            redisService.set("goodsStock:" + goods.getId(), String.valueOf(goods.getStock()));
        }
    }

    public Boolean decreaseStock(Long goodsId) {
        Long stock = Long.valueOf(stringRedisTemplate.opsForValue().get("goodsStock:" + goodsId));
        if (stock <= 0) {
            return false;
        }
        stock--;
        stringRedisTemplate.opsForValue().set("goodsStock:" + goodsId, String.valueOf(stock));
        return true;
    }
}
RabbitMQ 发送者实现
@Component
public class RabbitMQSender {

    @Autowired
    private AmqpTemplate amqpTemplate;

    public void sendOrderInfo(OrderInfo orderInfo) {
        String msg = JSONObject.toJSONString(orderInfo);
        amqpTemplate.convertAndSend("seckillExchange", "seckill.key", msg);
    }
}

控制器实现

@RestController
@RequestMapping("/seckill")
public class SeckillController {

    @Autowired
    private SeckillService seckillService;

    @PostMapping("/doSeckill")
    public Result doSeckill(Long userId, Long goodsId) {
        return seckillService.seckill(userId, goodsId);
    }

    @PostMapping("/getResult")
    public Result getResult(Long userId, Long goodsId) {
        return seckillService.getResult(userId, goodsId);
    }
}

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/register")
    public Result registerUser(User user) {
        return Result.success(userService.registerUser(user));
    }

    @PostMapping("/login")
    public Result login(String name, String password) {
        User user = userService.getUserByName(name);
        if (user != null && user.getPassword().equals(password)) {
            return Result.success(user);
        } else {
            return Result.error("用户名或密码错误");
        }
    }
}

@RestController
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    @GetMapping("/{goodsId}")
    public Result getGoodsById(@PathVariable Long goodsId) {
        return Result.success(goodsService.getGoodsById(goodsId));
    }

    @GetMapping("/all")
    public Result getAllGoods() {
        return Result.success(goodsService.getAllGoods());
    }
}

@RestController
@RequestMapping("/seckillGoods")
public class SeckillGoodsController {

    @Autowired
    private SeckillGoodsService seckillGoodsService;

    @GetMapping("/{goodsId}")
    public Result getSeckillGoodsByGoodsId(@PathVariable Long goodsId) {
        return Result.success(seckillGoodsService.getSeckillGoodsByGoodsId(goodsId));
    }

    @GetMapping("/all")
    public Result getAllSeckillGoods() {
        return Result.success(seckillGoodsService.getAllSeckillGoods());
    }
}

工具类

Result 工具类
public class Result {

    private Integer code;
    private String message;
    private Object data;

    public static Result success(Object data) {
        Result result = new Result();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }

    public static Result error(String message) {
        Result result = new Result();
        result.setCode(500);
        result.setMessage(message);
        result.setData(null);
        return result;
    }

    // getters and setters
}

应用启动类

@SpringBootApplication
@EnableTransactionManagement
@EnableJpaRepositories
public class SeckillApplication {

    public static void main(String[] args) {
        SpringApplication.run(SeckillApplication.class, args);
    }
}

以上代码示例是一个完整的秒杀功能实现,包含了用户、商品、秒杀商品、秒杀订单、订单等相关功能的实现。您可以根据实际需求进行调整和扩展。

你可能感兴趣的:(java,数据库,开发语言,spring,boot,后端)