spring boot+vue个人博客一:(后端)搭建spring boot脚手架

系列大纲
GitHub(还没开发完成)
在线演示(还没部署)
第一章:(后端)搭建spring boot脚手架:https://blog.csdn.net/grd_java/article/details/107452826
第二章:权限整合shiro+jwt,完成后端接口:https://blog.csdn.net/grd_java/article/details/107481570
第三章:搭建前端vue整合element ui脚手架:https://blog.csdn.net/grd_java/article/details/107498140
持续更新中

一、搭建数据库

/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 80017
 Source Host           : localhost:3306
 Source Schema         : myblog

 Target Server Type    : MySQL
 Target Server Version : 80017
 File Encoding         : 65001

 Date: 20/07/2020 17:32:56
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for m_blog
-- ----------------------------
DROP TABLE IF EXISTS `m_blog`;
CREATE TABLE `m_blog`  (
  `id` char(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '博客id',
  `user_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户id',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '博客标题',
  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '简介内容',
  `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '内容',
  `gmt_create` datetime(0) NOT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `status` tinyint(4) NOT NULL COMMENT '发布状态',
  `gmt_modified` datetime(0) NOT NULL COMMENT '修改时间',
  `is_delete` tinyint(1) NOT NULL COMMENT '逻辑删除1删除,0未删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of m_blog
-- ----------------------------

SET FOREIGN_KEY_CHECKS = 1;


/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 80017
 Source Host           : localhost:3306
 Source Schema         : myblog

 Target Server Type    : MySQL
 Target Server Version : 80017
 File Encoding         : 65001

 Date: 20/07/2020 17:34:06
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for m_user
-- ----------------------------
DROP TABLE IF EXISTS `m_user`;
CREATE TABLE `m_user`  (
  `id` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户id',
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
  `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '头像',
  `email` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
  `status` int(5) NOT NULL COMMENT '状态',
  `gmt_created` datetime(0) NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime(0) NOT NULL COMMENT '更新时间',
  `is_delete` tinyint(1) NOT NULL COMMENT '逻辑删除1删除,0未删除',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `UK_USERNAME`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of m_user
-- ----------------------------
INSERT INTO `m_user` VALUES ('1', 'markerhub', 'https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/5a9f48118166308daba8b6da7e466aab.jpg', NULL, '96e79218965eb72c92a549dd5a330112', 0, '2020-04-20 10:44:01', '0000-00-00 00:00:00', 0);

SET FOREIGN_KEY_CHECKS = 1;

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

记住每个表加两条数据

二、分布式环境搭建

1、创建父工程引入依赖

<?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>com.yzpnb</groupId>
    <artifactId>myblog</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <!--spring boot 父依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
    </parent>
    <!--依赖-->
    <dependencies>
        <!--spring boot test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--lombook-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <!--管理依赖-->
    <dependencyManagement>
        <dependencies>
            <!--spring cloud-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR4</version>
                <type>pom</type>
                <scope>import</scope>
                <!--注意这里使用<scope>import</scope>是为了预防jar包依赖引用
                import只能用于<dependencyManagement>中并且设置<type>pom</type>的依赖中。
                可以使子模块不使用父模块的引用jar包
                如果不设置此项,就会报错(你可以注释掉试试),因为子模块在引用某些jar包时,会引用父模块中的jar包
                从而jar包冲突-->
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

在这里插入图片描述

2、创建子模块和全局模块,引入依赖

<?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">
    <parent>
        <artifactId>myblog</artifactId>
        <groupId>com.yzpnb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common</artifactId>

    <dependencies>
        <!--mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--mybatis plus 代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认):这是代码生成器需要的依赖-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>
        <!--代码生成器需要的依赖,swagger,处理ApiModel-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>

在这里插入图片描述

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

在这里插入图片描述

3、定制统一返回接口

封装状态码

在这里插入图片描述

package com.yzpnb.common_utils;

public interface ResultCode {
    /**
     * 状态码 
     * 20000:代表成功
     * 20001:代表错误
     */
    public static Integer SUCCESS =20000;
    public static Integer ERROR =20001;
}
统一返回结果

在这里插入图片描述

package com.yzpnb.common_utils;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class Result {
    /**
     * 当我们返回json字符串的时候,可以按以下规则
     * {
     * 	"sucess":布尔值, 	//表示是否响应成功
     * 	"code":数字,		//响应码
     * 	"message":字符串,	//返回信息
     * 	"data":HashMap,		//返回的数据
     * }
     *
     * 创建成员变量
     */

    @ApiModelProperty(value="是否成功")
    private Boolean success;

    @ApiModelProperty(value="状态码")
    private Integer code;

    @ApiModelProperty(value="返回消息")
    private String message;

    @ApiModelProperty(value="返回数据")
    private Map<String,Object> data=new HashMap<>();

    /**私有化构造方法:就是说除了Result类本身,其它类不能new Result类的对象了**/
    private Result(){}

    /**获取一个私有的Result对象。Result本身是可以new 对象,无论私有与否**/
    private static Result result=new Result();

    /**处理响应成功的静态方法**/
    public static Result ok(){
        result.setSuccess(true);            //设置为true,表示处理响应成功
        result.setCode(ResultCode.SUCCESS); //调用我们提供状态码的接口,设置状态码
        result.setMessage("成功");          //设置提示信息
        return result;                      //返回对象,外键不能new,只能通过静态方法获取对象

    }
    /**处理响应失败的静态方法**/
    public static Result error(){
        result.setSuccess(false);         //设置为false,表示处理响应失败
        result.setCode(ResultCode.ERROR); //调用我们提供状态码的接口,设置状态码
        result.setMessage("失败");        //设置提示信息
        return result;
    }

    /**设置值方法*/
    public Result succes(Boolean b){
        this.success=b;
        return this;
    }

    public Result code(Integer i){
        this.code=i;
        return this;
    }

    public Result message(String str){
        this.message=str;
        return this;
    }

    public Result data(String key ,Object value){
        this.data.clear();//先清空,因为我这里是单例设计模式,data中数据永远都在
        this.data.put(key,value);
        return this;
    }

    public Result data(Map<String , Object> map){
        this.setData(map);
        return this;
    }
}

4、整合swagger2

创建公共配置模块配置

在这里插入图片描述
在这里插入图片描述

package com.yzpnb.service_base.config;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2//表中此类为Swagger2
public class SwaggerConfig {
    @Bean
    public Docket webApiConfig() {
        List<Parameter> pars = new ArrayList<Parameter>();
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")//分组名
                .apiInfo(webApiInfo())//在线文档的信息,传入ApiInfo对象,就是下面内个方法返回的对象
                .select()
                .paths(Predicates.not(PathSelectors.regex("/admin/.*")))//路径中包含admin时不显示信息
                .paths(Predicates.not(PathSelectors.regex("/error/.*")))
                .build();
    }

    private ApiInfo webApiInfo() {
        return new ApiInfoBuilder()
                .title("gulischool 接口 API 文档")
                .description("展示先做基础功能,后面再添加业务")
                .termsOfServiceUrl("https://www.yzpnb.com/aa/")
                .version("1.0")
                .contact(new Contact("Helen","http://yzpnb.com","[email protected]"))
                .build();
    }

}

5、代码生成器

在这里插入图片描述

在这里插入图片描述

package com.yzpnb;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

/**
 * @author
 * @since 2018/12/13
 */
public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\IdeaProjects\\myblog\\service\\service_blog" + "/src/main/java"); //输出目录,生成的代码最终输出的地方,请写你的项目的绝对路径
        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER_STR); //主键策略,ID_WORKER表示默认Integer,ID_WORKER_STR表示字符型
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/myblog?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置(生成的包名)
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.yzpnb");
        pc.setModuleName("service_blog"); //模块名 com.yzpnb.service_blog

        pc.setController("controller"); //com.yzpnb.eduservice.controller
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("m_user","m_blog");//你要为哪个表生成代码
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}

在这里插入图片描述

6、启动类

package com.yzpnb.service_blog;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan("com.yzpnb")
public class BlogApplication {
    public static void main(String[] args) {
        SpringApplication.run(BlogApplication.class,args);
    }
}

在这里插入图片描述

7、整合MyBatis Plus

1、application.yaml

server:
  port: 8001 #微服务端口号为8001
spring:
  application:
    name: service-blog #服务名
#  profiles:
#    active: dev #环境设置 dev表示构建阶段,test表示测试阶段,prod表示发布阶段
  datasource: #数据源
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/myblog?serverTimeZone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
  jackson: #我们的时区是东八区,应该加8个小时,时区显示格式也需要改成我们想要的
    date-format: yyyy-MM-DD HH:mm:ss
    time-zone: GMT+8
mybatis-plus:
  mapper-locations: classpath:com/yzpnb/service_blog/mapper/xml/*.xml #配置mapper xml文件的路径

在这里插入图片描述

2、配置类

package com.yzpnb.service_base.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan(value="com.yzpnb.*.mapper")
public class MpConfiguration {
	//分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

在这里插入图片描述

3、配置自动填充

在这里插入图片描述

package com.yzpnb.service_base.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component//将组件注入到IOC容器
public class MyMpMetaObjectHandler implements MetaObjectHandler{
    @Override
    public void insertFill(MetaObject metaObject) {
        /**注意这里的监听字段gmtCreate和gmtModified是java属性名,不是字段名*/
        this.setFieldValByName("gmtCreate",new Date(),metaObject);
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }
}

刚刚写完第二章,发现自动填充这里字段名写错了 this.setFieldValByName("gmtCreate",new Date(),metaObject);
我在数据库中字段叫gmtCreated,所以如果你使用我的sql代码生成数据库表
请到数据库中将这个字段都修改为gmtCreate

4、测试

在这里插入图片描述在这里插入图片描述

8、全局异常

如果你需要处理全局异常,就需要web包

在这里插入图片描述

创建自定义异常
package com.yzpnb.service_base.handler;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 自定义异常类
 * */

@Data//为类中成员变量自动生成get set toString
@AllArgsConstructor //自动生成有参构造方法,参数是所有参数
@NoArgsConstructor  //自动生成无参构造
public class CustomExceptionHandler extends RuntimeException{

    private Integer code;//状态码

    private String message;//异常信息
}

在这里插入图片描述

创建通用异常,引用自定义异常
package com.yzpnb.service_base.handler;

import com.yzpnb.common_utils.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice//全局异常处理、全局数据绑定、全局数据预处理
public class MyExceptionHandler  {

    /**处理自定义异常*/
    @ExceptionHandler(CustomExceptionHandler.class)//表示此方法只对我们自己定义的这个异常有效
    @ResponseBody
    public Result customError(CustomExceptionHandler e){//参数就是我们自定义异常类的对象
        e.printStackTrace();//父类提供的方法
        return Result.error().code(e.getCode()).message(e.getMessage());//将统一返回结果的状态码和提示信息,换为自定以异常的
    }
}

在这里插入图片描述

controller测试
@GetMapping("selectAll")
    public Result selectAll(){
        List<MUser> list = mUserService.list();
        if(true){
            throw new CustomExceptionHandler(20000,"自定义异常");//只要我们抛这个异常,那么MyExceptionHandler中的方法就会执行,因为设置了方法只监听这个异常
        }
        return Result.ok().data("all",list);
    }

在这里插入图片描述在这里插入图片描述

9、解决跨域问题

在这里插入图片描述

package com.yzpnb.service_base.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 解决跨域问题
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}
第二节:整合shiro+jwt,完成后端接口开发
https://blog.csdn.net/grd_java/article/details/107481570

猜你喜欢

转载自blog.csdn.net/grd_java/article/details/107452826