基于SpringBoot2.1.x框架的一些常用开发介绍


一、建立初始的工程

可以使用官网https://start.spring.io/,或者 idea来新建springboot工程。前提条件是安装好jdk8和maven3.2以上版本。使用的idea也要做好jdk、maven、utf-8编码格式设置。

在pom.xml文件,可以修改springboot的版本号。重新导入maven即可。

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.6.RELEASEversion>
        <relativePath/> 
    parent>

 1.1 先不连接数据库,启动project。

  如果报数据库的错,给注释 @SpringBootApplication 添加参数。

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

 1.2 通常是为了开发web项目, 所以添加web的依赖。

  因为已经指定了parent是2.1.6.RELEASE版本的spring-boot-starter-parent,这里web的版本不需要指定。

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

  添加一个用于测试的controller。访问 http://localhost:8010/user/test , 正常即可。

@Controller
@RequestMapping("user")
public class UserController {
    @RequestMapping("test")
    @ResponseBody
    public String test(){
        return "test";
    }
}

1.3 辅助工具

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-devtoolsartifactId>
            <scope>runtimescope>
            <optional>trueoptional>
        dependency>

        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>

 

二、连接数据库

2.1 数据库使用mysql5.7,mybatis3作为ORM。

  mysql5.7在win和linux下的安装操作,参考我的其它两篇博客:“”,“”。

  再介绍docker安装mysql5.7的做法。拉取iamge,docker pull centos/mysql-57-centos7。

[root@master ~]# docker images 
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
nginx                     latest              a1523e859360        2 weeks ago         127MB
mongo                     latest              bcef5fd2979d        2 weeks ago         386MB
centos/mysql-57-centos7   latest              f83a2938370c        5 months ago        452MB
redis                     3.2                 87856cc39862        17 months ago       76MB

  启动mysql容器。我没有使用数据卷 -v,挂载到宿主机。

docker run -di -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=123456 centos/mysql-57-centos7

  mysql数据库,建新库使用utf8字符集,排序建议使用utf8_unicode_xx。

  建立一张user测试表。

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `telphone` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `password` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `nick_name` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `gender` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `telphone_unique_index` (`telphone`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

2.2 添加数据库连接和mybatis3的依赖,以及逆向工程。

        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>1.3.1version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.3version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.47version>
        dependency>

  删除启动类上的 exclude = DataSourceAutoConfiguration.class 这个参数。

spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
name: dianpingdb
url: jdbc:mysql://master:3306/dbname?useUnicode=true&characterEncoding=UTF-8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
mybatis:
mapper-locations: classpath:com/xxx/mapper/*.xml
type-aliases-package: com.xxx.pojo.entity

# 为了打印sql
logging:
level:
com.xxx.mapper: debug

debug: true

  

  使用mybatis 的逆向工程, 参考 http://mybatis.org/generator/ 。第一步,使用插件。

    <build>
        
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.mybatis.generatorgroupId>
                    <artifactId>mybatis-generator-maven-pluginartifactId>
                    <version>1.3.5version>
                    <dependencies>
                        <dependency>
                            <groupId>org.mybatis.generatorgroupId>
                            <artifactId>mybatis-generator-coreartifactId>
                            <version>1.3.5version>
                        dependency>
                        <dependency>
                            <groupId>mysqlgroupId>
                            <artifactId>mysql-connector-javaartifactId>
                            <version>5.1.47version>
                        dependency>
                    dependencies>
                    <executions>
                        <execution>
                            <id>mybatis generatorid>
                            <phase>packagephase>
                            <goals>
                                <goal>generategoal>
                            goals>
                        execution>
                    executions>
                    <configuration>
                        
                        <verbose>trueverbose>
                        
                        <overwrite>trueoverwrite>
                        <configurationFile>
                            src/main/resources/mybatis-generator.xml
                        configurationFile>
                    configuration>
                plugin>
            plugins>
        pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

  第二步,添加文件 mybatis-generator.xml

DOCTYPE generatorConfiguration PUBLIC
        "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="simple" targetRuntime="MyBatis3Simple">
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://master:3306/dbname"
                        userId="root" password="123456"/>
        
        <javaModelGenerator targetPackage="com.xxx.pojo.entity"
                            targetProject="src/main/java"/>

        
        <sqlMapGenerator targetPackage="com.xxx.mapper"
                         targetProject="src/main/resources"/>
        
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.xxx.mapper"
                             targetProject="src/main/java"/>

        <table tableName="user" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" selectByExampleQueryId="false">
            <generatedKey column="id" sqlStatement="MySql" identity="true" />
        table>

    context>
generatorConfiguration>

  第三步,maven启动。

  mvn mybatis-generator:generate

 2.3 读取数据库记录测试

    @GetMapping("get")
    @ResponseBody
    public User getUserById(@RequestParam Integer id){
      return  userService.getUserById(id);
    }
public interface UserService {
    User getUserById(Integer id);
}
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Override
    public User getUserById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }
}

 2.4 引入mybatis-plus

除了mybatis之外,还有集成度更高的 mybatis plus。

比如给定一个 User实体类。

添加依赖

      <dependency>
          <groupId>com.baomidougroupId>
          <artifactId>mybatis-plus-boot-starterartifactId>
          <version>3.2.0version>
      dependency>    

对应的 mapper接口

@Repository
public interface UserMapper extends BaseMapper {
    
}

以及service

public interface UserService extends IService {

}
@Service
public class UserServiceImpl extends ServiceImpl implements UserService {

}

 IService 和 ServiceImpl 都是 mybatis-plus提供的。

在controller里调用

@Autowired
UserService userService;
User user = userService.getById(1L);

三、规定通用返回的格式和全局异常处理。

3.1 通用返回

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class Result {

    private int code;
    private String msg;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Object data;    // 不要返回null值。

    public static Result success(Object data) {
        return Result.builder()
                .data(data).msg("success").code(200)
                .build();
    }

    public static Result create(ErrorCode errorCode){
        return Result.builder()
                .msg(errorCode.msg).code(errorCode.code)
                .build();
    }
    
}

新建错误码枚举类

public enum ErrorCode {

    OBJECT_NOT_FOUNT(10001, "请求对象不存在"),
    UNKNOWN_ERROR(10002, "未知错误"),
    NO_HANDLER_FOUND(10003, "找不到页面,有可能是提交的路径或参数不对。"),
    PARAMETER_ERROR(10004, "请求的参数不对"),
    ;

    public int code;
    public String msg;

    ErrorCode(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

}

 测试返回内容

    @GetMapping("get")
    @ResponseBody
    public Result getUserById(@RequestParam Integer id) throws GlobalException {
        User userById = userService.getUserById(id);
        if(userById==null){
            // 统一返回错误码
            return Result.create(ErrorCode.OBJECT_NOT_FOUNT);
        }
        return Result.success(userById);
    }

3.2 全局异常处理

 在错误码的基础上,新建自定义异常类。

@Data
public class GlobalException extends Exception{

    private ErrorCode errorCode;

    public GlobalException(ErrorCode errorCode) {
        super();
        this.errorCode = errorCode;
    }

}

 新建异常处理handler的类。

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    Result handlerException(HttpServletRequest request,
                            HttpServletResponse response,
                            Exception ex){
        if(ex instanceof GlobalException){
            // 自定义的异常类
            GlobalException exception = (GlobalException) ex;
            return Result.create(exception.getErrorCode());
        }else if(ex instanceof NoHandlerFoundException){
            // 404 没找到处理页面
            return Result.create(ErrorCode.NO_HANDLER_FOUND);
        }else if(ex instanceof MissingServletRequestParameterException){
            // 提交的参数不对
            return Result.create(ErrorCode.PARAMETER_ERROR);
        }else {
            return Result.create(ErrorCode.UNKNOWN_ERROR);
        }
    }
}

为了阻止默认的404错误页面,要添加配置。

spring:
#出现错误时, 直接抛出异常,以下2个配置都要有。

mvc: throw-exception-if-no-handler-found: true resources: add-mappings: false

参考 https://www.jianshu.com/p/36505ac4d32a

测试controller

    @GetMapping("get")
    @ResponseBody
    public Result getUserById(@RequestParam Integer id) throws GlobalException {
        User userById = userService.getUserById(id);
        if(userById==null){
            // 统一返回错误码,当然也可以。
            // return Result.create(ErrorCode.OBJECT_NOT_FOUNT);
            // 这里尝试抛出异常,再统一做自定义的全局异常处理。
            throw new GlobalException(ErrorCode.OBJECT_NOT_FOUNT);
        }
        return Result.success(userById);
    }