ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

▶【SecKill】U1 项目框架搭建

2022-02-07 01:01:08  阅读:175  来源: 互联网

标签:SecKill String U1 kirin miaosha Result return public 搭建


▶【SecKill】U1 项目框架搭建

一、SpringBoot环境搭建

1、新建Maven Project

【报错】Could not get the value for parameter encoding for plugin execution default-resources

原因:maven包无法下载下来

【解决方法】选中项目右键 → Maven → Update Proejct

等更新完就可以再启动项目试试(一般情况下网络顺畅稳定,此方法可行),如果还是不行就去网上找到对应版本jar下载下来的,手动放到maven指定文件夹里

 

2、在pom.xml中添加依赖

 

3、搭建 简易 的SpringBoot框架

(1)删除src/test/java测试类

 

(2)改包名

【注】SpringBoot是在SpringMVC的基础上,做了封装。

SpringBoot开发程序 = SpringMVC(controller调用service,service调用DAO 的分层结构开发)

 

(3)分层结构controller、service、dao

① controller

 ② service

③ dao

 

(4)测试Demo1:新建DemoController类,添加代码(官网Spring Quickstart Guide简易项目代码

复制代码
package com.kirin.miaosha.controller;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@EnableAutoConfiguration
public class DemoController {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
    
    public static void main(String[] args) throws Exception {
        SpringApplication.run(DemoController.class, args);
    }
}
复制代码

 

 (5)运行测试

  成功!

 

4、测试Demo2

(1)在com.kirin.miaosha中新建class类:MainApplication.class

 

(2)将DemoController.java中的这2段放入MainApplication.class中

DemoController.java:

 

MainApplication.class:

复制代码
package com.kirin.miaosha;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(MainApplication.class, args);
    }
}
复制代码

 

(3)运行MainApplication.class

【注】运行新的Tomcat前,先按停止键,暂停之前正在运行的Tomcat

 

5、Controller中的方法:

(1)rest api json输出

【例】

新建com.kirin.miaosha.result包

在com.kirin.miaosha.result包下,新建Result类

在Result类中,定义变量code、msg、data

生成get()、set()方法

复制代码
package com.kirin.miaosha.result;

public class Result<T> { //<T>:泛型(广泛的类型)
    private int code;
    private String msg;
    private T data;  //不知道data的类型,则定义为T,在类后声明<T>,表示T为泛型
    
    //生成get、set方法
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}
复制代码

 

DemoController.java:

复制代码
package com.kirin.miaosha.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.kirin.miaosha.result.Result;

@Controller
public class DemoController {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
    
    //Controller中的方法:
    //1.rest api json输出
    //【例】com.kirin.miaosha.result包下Result类
    @RequestMapping("/hello")
    @ResponseBody
    String hello() {
        Result.success(data);
        return new Result(0,"success","helo,kirin");
    }
    
    @RequestMapping("/helloError")
    @ResponseBody
    String helloError() {
        Result.error(CodeMsg);
        return new Result(500102,"XXX");
        return new Result(500101,"XXX");
        return new Result(500100,"session失效");
    }
    
}
复制代码

 

Result.java:

 

CodeMsg.java:

复制代码
package com.kirin.miaosha.result;

public class CodeMsg {
    private int code;
    private String msg;
    
    //定义通用异常
    public static CodeMsg SUCCESS = new CodeMsg(0, "success");
    public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务端异常");

    private CodeMsg(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    
    //生成get、set方法(后来发现用不到set方法,删除)
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}
复制代码

 

Result.java:

复制代码
package com.kirin.miaosha.result;

public class Result<T> { //<T>:泛型(广泛的类型)
    private int code;
    private String msg;
    private T data;  //不知道data的类型,则定义为T,在类后声明<T>,表示T为泛型
    
    
    //com.kirin.miaosha.controller包下DemoController.java
    //成功时调用
    public static <T> Result<T> success(T data){
        return new Result<T>(data); //写完后报错:生成一个构造函数private Result(T data)
        
    }
    
    //失败时调用
    public static <T> Result<T> error(CodeMsg cm){ //报错:自动生成CodeMsg.java类
        return new Result<T>(cm); //写完后报错:生成一个构造函数private Result(CodeMsg cm)
    }
    
    //public static <T> Result<T> success(T data)报错后,自动生成的构造函数
    private Result(T data) {
        this.code = 0; //成功
        this.msg = "success";
        this.data = data;
    }
    
    //public static <T> Result<T> error(CodeMsg cm)报错后,自动生成的构造函数
    private Result(CodeMsg cm) {
        if(cm == null) {
            return;
        }
        this.code = cm.getCode();
        this.msg = cm.getMsg();  
    }

    
    //生成get、set方法(后来发现用不到set方法,删除)
    public int getCode() {
        return code;
    }public String getMsg() {
        return msg;
    }public T getData() {
        return data;
    }
}
复制代码

 

DemoController.java:

复制代码
package com.kirin.miaosha.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kirin.miaosha.result.CodeMsg;
import com.kirin.miaosha.result.Result;

@Controller
public class DemoController {
    @RequestMapping("/")
    @ResponseBody
    String home() {
        return "Hello World!";
    }
    
    //Controller中的方法:
    //1.rest api json输出
    //【例】com.kirin.miaosha.result包下Result类
    @RequestMapping("/hello")
    @ResponseBody
    public Result <String> hello() {
        return Result.success("helo,kirin");
//        return new Result(0,"success","helo,kirin");
    } 
    
    @RequestMapping("/helloError")
    @ResponseBody
    public Result <String> helloError() {
        return Result.error(CodeMsg.SERVER_ERROR);
//        return new Result(500100,"session失效");
    }
    
}
复制代码

运行MainApplication.java

  成功!

 

(2)前端页面

 

 

二、集成Thymeleaf(页面模板=JSP),Result结果封装

1、添加Thymeleaf依赖(前端=JSP)

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

 

2、配置文件

复制代码
spring.thymeleaf.cache=false
spring.thymeleaf.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
复制代码

 

3、Result结果封装

(1)DemoController.java:

//U1-2 集成Thymeleaf(页面模板=JSP),Result结果封装
@RequestMapping("/thymeleaf")
public String Thymeleaf() { //返回页面模板
    return "hello";
    //在配置文件中配置hello的页面模板
}  

 

(2)在配置文件中配置hello的页面模板

① 新建templates文件夹

② 在配置文件中配置hello的页面模板:src/main/resources/templates/hello.html

复制代码
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
  <p th:text="'hello:'+${name}" ></p>
</body>
</html>
复制代码

 

③ 定义一个对象

复制代码
//U1-2 集成Thymeleaf(页面模板=JSP),Result结果封装
@RequestMapping("/thymeleaf")
public String Thymeleaf(Model model) { //返回页面模板
    model.addAttribute("name","kirin"); //定义一个对象
    return "hello";
    //在配置文件中配置hello的页面模板:src/main/resources/templates/hello.html
}  
复制代码

 

运行MainApplication.java

 成功!

【报错】Project configuration is not up-to-date with pom.xml. Select: Maven->Update Project... from the project context menu or use Quick Fix.

原因:项目的配置没有及时更新with这个pom.xml文件,所以更新一下配置文件即可。

 

 

三、集成Mybatis(数据库)+Druid

1、添加pom.xml依赖

<!-- 4.添加Mybatis依赖 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

 

2、添加配置mybatis

① 新建包domain:访问根数据库的表

② 在application.properties中添加配置mybatis

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

 

③ 在application.properties中添加配置druid(连接池)

复制代码
# druid
spring.datasource.url=jdbc:mysql://localhost:3306/miaosha
spring.datasource.username=root
spring.datasource.password=12345
spring.datasource.driver-class-name=com.mysql.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.minIdle=1
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxOpenPreparedStatements=20
复制代码

 

④ 在application.properties中添加配置Mysql

复制代码
<!-- 5.添加Mysql依赖 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.5</version>
</dependency>
复制代码

 

⑤ 连接数据库

A.新建数据库miaosha

CREATE DATABASE `miaosha`;
USE `miaosha`;

 

B.新建数据库表user

C.新建user表对应的domain对象

复制代码
package com.kirin.miaosha.domain;

public class User {
    private int id;
    private String name;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
复制代码

 

D.新建调用user表的接口UserDao

复制代码
package com.kirin.miaosha.dao;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.kirin.miaosha.domain.User;

@Mapper
public interface UserDao {
    
    @Select("select * from user where id = #{id}")
    public User getById(@Param("id") int id);

}
复制代码

 

E.新建UserService

复制代码
package com.kirin.miaosha.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kirin.miaosha.dao.UserDao;
import com.kirin.miaosha.domain.User;

@Service
public class UserService {
    
    @Autowired
    UserDao userDao;
    
    public User getById(int id) {
        return userDao.getById(id);
    }
}
复制代码

 

F.DemoController.java

在数据库插入1条记录

复制代码
//U1-4 数据库测试:获取id
@Autowired
UserService userService;
    
@RequestMapping("/db/get")
@ResponseBody
public Result<User> dbGet() {
    User user = userService.getById(1);
    return Result.success(user);
}
复制代码

 

G.运行

 成功!

 

H.数据库测试2:事务

DemoController.java:

在UserDao.java写插入语句

UserService.java:

 

I. 运行

数据库中 id=2,name=2222 的记录没有插入,因为这是一条事务

若去掉事务标签,

数据库中 id=2,name=2222 的记录插入

 

 

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

1、Linux服务器准备工作

(1)Navicat连接Linux服务器的MYSQL

(2)新建miaosha数据库

① 连接数据库

启动服务

systemctl start mysqld.service

登录

mysql -uroot -p

密码为空

 

② 新建数据库:create database 数据库名;

create database miaosha;

设置数据库编码:以utf8为例

set names utf8;

选择数据库:use 数据库名;

use miaosha;

在Navicat出现miaosha数据库

 

③ 新建数据库表user

在数据库插入1条记录

 

④ 修改application.properties中服务器地址

⑤ 运行

 

2、安装Redis

(1)安装包redis-4.0.2.tar.gz

(2)将安装包拉进root文件夹下

(3)解压

tar -zxvf redis-4.0.2.tar.gz

解压后,出现目录redis-4.0.2

移动该文件夹到 

mv redis-4.0.2 /usr/local/redis

 

(4)make

① 进入移动后的目录

 

② 用4个CPU make一下,可加快编译速度

make -j 4

make完成后,查看目录

 

③ 把编译完成的可执行文件添加到目录中

make install

 完成!

 

④ 修改 redis.conf 配置文件

查看 redis.conf 配置文件

vi redis.conf

 

⑤ 修改 redis.conf 配置文件

    按「i」:进入插入模式
    按「ESC」:从插入模式切换为命令行模式
    打 :w  保存文件但不退出vi
    打 :wq  保存文件并退出vi

A. 使其可以让所有服务器访问

 

B. 允许后台执行

 

⑥ 查看Redis服务器是否可以访问

运行Redis服务器

redis-server ./redis.conf

 

(5)执行 install_server.sh,生成系统服务

进入 utils 下

 

执行 install_server.sh,生成系统服务

./install_server.sh

 

3、集成Redis

(1)在pom.xml添加Jedis和Fastjson依赖

复制代码
<!-- 6.添加Jedis依赖 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
    
<!-- 7.添加Fastjson依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.38</version>
</dependency>    
复制代码

 

(2)在application.properties配置Redis

#redis
redis.host=192.168.xx.xx
redis.port=6379
redis.timeout=3
redis.password=xxxxx
redis.poolMaxTotal=10
redis.poolMaxIdle=10
redis.poolMaxWait=3

 

(3)

① 新建redis包

② 新建RedisConfig.java,加入配置文件的参数和方法

 

③ 新建其余7个class类

BasePrefix.java:

复制代码
package com.kirin.miaosha.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;
    }
    
    public int expireSeconds() { //默认0代表永不过期
        return expireSeconds;
    }

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

}
复制代码

 

KeyPrefix.java:

复制代码
package com.kirin.miaosha.redis;

public interface KeyPrefix {
    
    public int expireSeconds(); //有效期
    
    public String getPrefix(); //前缀
    
}
复制代码

 

MiaoshaUserKey.java:

复制代码
package com.kirin.miaosha.redis;

public class MiaoshaUserKey extends BasePrefix{

    public static final int TOKEN_EXPIRE = 3600*24 * 2;
    private MiaoshaUserKey(int expireSeconds, String prefix) {
        super(expireSeconds, prefix);
    }
    public static MiaoshaUserKey token = new MiaoshaUserKey(TOKEN_EXPIRE, "tk");
}
复制代码

 

OrderKey.java:

复制代码
package com.kirin.miaosha.redis;

public class OrderKey extends BasePrefix {

    public OrderKey(int expireSeconds, String prefix) {
        super(expireSeconds, prefix);
    }

}
复制代码

 

RedisPoolFactory.java:

复制代码
package com.kirin.miaosha.redis;

@Service
public class RedisPoolFactory {

    @Autowired
    RedisConfig redisConfig;
    
    @Bean
    public JedisPool JedisPoolFactory() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
        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;
    }
    
}
复制代码

 

RedisService.java:

复制代码
package com.kirin.miaosha.redis;

@Service
public class RedisService {
    
    @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); //将获取的值,从String类型转换成bean类型
            return t;
        }finally {
            returnToPool(jedis);
        }
    }
    
    //设置对象
    public <T> boolean set(KeyPrefix prefix, String key,  T value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String str = beanToString(value); //将设置的值,从bean类型转换成String类型
            if(str == null || str.length() <= 0) {
                return false;
            }
            //生成真正的key
            String realKey = prefix.getPrefix() + key;
            int seconds = prefix.expireSeconds();
            if(seconds <= 0) {
                jedis.set(realKey, str);
            }else {
                jedis.setex(realKey, seconds, str);
            }
            return true;
        }finally {
            returnToPool(jedis);
        }
    }
    
    //判断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);
        }
    }
    
    //将设置的值,从bean类型转换成String类型
    private <T> String beanToString(T value) {
        if(value == null) { //若空,直接返回
            return null;
        }
        Class<?> clazz = value.getClass();
        if(clazz == int.class || clazz == Integer.class) { //若是int类型,直接写入
            return ""+value;
        }else if(clazz == String.class) { //若是String类型,直接写入
            return (String)value;
        }else if(clazz == long.class || clazz == Long.class) { //若是long类型,直接写入
            return ""+value;
        }else {
            return JSON.toJSONString(value);
        }
    }
    
    //将获取的值,从String类型转换成bean类型
    @SuppressWarnings("unchecked")
    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) { //若是int类型,强转为int类型
            return (T)Integer.valueOf(str);
        }else if(clazz == String.class) { //若是String类型,直接输出
            return (T)str;
        }else if(clazz == long.class || clazz == Long.class) { //若是long类型,强转为long类型
            return (T)Long.valueOf(str);
        }else {
            return JSON.toJavaObject(JSON.parseObject(str), clazz);
        }
    }
    
    private void returnToPool(Jedis jedis) {
         if(jedis != null) {
             jedis.close();
         }
    }
}
复制代码

 

UserKey.java:

复制代码
package com.kirin.miaosha.redis;

public class UserKey extends BasePrefix{

    private UserKey(String prefix) {
        super(prefix);
    }
}
复制代码

 

DemoController.java:

 

测试:

 

标签:SecKill,String,U1,kirin,miaosha,Result,return,public,搭建
来源: https://www.cnblogs.com/kirin1105916774/p/15866744.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有