IDEA搭建多模块maven项目

新建maven项目作为多模块的parent项目

  • 删除parent项目中的src目录
  • 修改parent项目中pom的 <packaging>pom</packaging>

新建模块

  • 在这个项目上右键,新建模块,parent保证是当前项目,保证模块目录在项目下面
    • 模块分别为api mapper service common pojo
    • 以上依赖关系:
      • 所有模块都依赖公共模块common
      • mapper依赖于pojo
      • service依赖于mapper
      • api依赖于service

在parent项目中配置 pom

  • 继承spring-boot依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.7.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
  • 配置项目要用到的依赖
    • spring-boot
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    • mybatis
        <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.1</version>
    </dependency>
    
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.1</version>
    </dependency>
    
    • mysql连接
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    

api 模块搭建restful风格api

  • resource源目录配置yml

    • application.yml 服务环境分离,公共部分抽取
        server:
          port: 8080
        spring:
          profiles:
            active: test #指定使用哪个环境
            include: common #包括公共部分
        
        ---
        server:
          port: 8080
        spring:
          profiles: test  #指定属于哪个环境
        
        ---
        server:
          port: 8081
        spring:
          profiles: prod  #指定属于哪个环境
    
    • application-common.yml 公共部分
    logging:
      pattern:
        console: "[%thread] %-5level %logger{36} - %msg%n"
      level:
        tech.dclass.dclasspay.mapper: DEBUG   #mybatis sql log
    
    mybatis:
      configuration:
        map-underscore-to-camel-case: false
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.kcclass.pojo
    
    • application-prod.yml 正式环境
    spring: #数据库连接
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: *********
        password: *********
        url: jdbc:mysql://172.17.0.5:61554/kcclass-prod?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&&allowMultiQueries=true
        type: com.zaxxer.hikari.HikariDataSource  #Hikari数据源,默认也是这个数据源
        hikari:
          connection-timeout: 30000 #等待分配超时时间
          minimum-idle: 5 #最小连接
          maximum-pool-size: 20 #最大连接
          auto-commit: true #自动提交
          idle-timeout: 60000 #连接超时时间
          pool-name:  HikariDataSource  #连接池名称
          max-lifetime: 1800000 #生命时长,超过且没使用,则被回收
          connection-test-query: select 1 #测试查询
    
      redis:  #通用redis
        host: 122.51.217.181
        password: *********
        database: 15
        port: 6379
    
    • application-test.yml 测试环境,和正式环境只是具体值不同
  • 简单测试接口

#TestController.java
package com.itnetschool.controller;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {


    @GetMapping("/test")
    public String test(){
        return "test";
    }
}
#ApiApplication.java
package com.itnetschool;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.itnetschool.mapper")
public class ApiApplication {

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

启动Springboot启动类ApiApplication,访问http://localhost:8080/test

Mybatis Generator的使用(mybatis 逆向代码生成器,生成mapper和pojo)

  • 配置maven插件,在api模块的pom中配置如下
<build>

    <plugins>
        <!--mvn mybatis-generator:generate-->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.7</version>

            <configuration>
                <overwrite>true</overwrite>
            </configuration>
        </plugin>

        <plugin>   <!--springboot打包插件-->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>2.1.7.RELEASE</version>
        </plugin>
    </plugins>
</build>
  • 在api模块的resource中新建generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
<!--    windows下路径, D:downloadsxxx.jar-->
    <classPathEntry location="D:mavenrepromysqlmysql-connector-java8.0.17mysql-connector-java-8.0.17.jar" />

    <context id="DB2Tables" targetRuntime="MyBatis3">

<!--        不再追加xml内容-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />

        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://sh-cdb-4*************m:61554/wxshell?characterEncoding=utf-8"
                        userId="root"
                        password= "**********">
            <!--SpringBoot 刨坑记(二)generator自动生成mybatis实体类时多出了***WithBLOBs和***Key类 https://blog.csdn.net/qq_38972117/article/details/84955780-->
            <property name="nullCatalogMeansCurrent" value="true" />

        </jdbcConnection>

        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <javaModelGenerator targetPackage="com.itnetschool.pojo" targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
<!--            <property name="trimStrings" value="true" />-->
        </javaModelGenerator>

        <sqlMapGenerator targetPackage="mapper"  targetProject="src/main/resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.itnetschool.mapper"  targetProject="src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <table tableName="user"  enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false"/>


    </context>
</generatorConfiguration>
  • 使用idea终端,切换到api目录 ,然后执行mvn mybatis-generator:generate,生成pojo及mapper。
  • 执行完之后,可以将mapper及pojo拷贝到对应的mapper及pojo模块中。mapper.xml还是保留在api的resource源码下

mybatis-plus搭建baseservice

  • 生成的mapper接口 继承 BaseMapper 接口
package com.itnetschool.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itnetschool.pojo.User;

public interface UserMapper extends BaseMapper<User> {
    int deleteByPrimaryKey(Long userid);

    int insert(User record);

    int insertSelective(User record);

    User selectByPrimaryKey(Long userid);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
}
  • 新建service接口 继承Iservice
package com.itnetschool.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.itnetschool.pojo.User;

public interface UserService extends IService<User> {

}

  • 新建service实现类 继承ServiceImpl 并实现UserService
package com.itnetschool.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itnetschool.mapper.UserMapper;
import com.itnetschool.pojo.User;
import com.itnetschool.service.UserService;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    
}

构建统一的格式化输出

  • ResultBean.java
package com.itnetschool.common.bean;

    import lombok.Data;
    
    import java.io.Serializable;
    
    @Data
    public class ResultBean<T> implements Serializable {
    
        /** 错误码. */
        private Integer code;
    
        /** 提示信息. */
        private String msg;
    
        /** 具体内容. */
        private T data;
    
        
        private static ResultBean initFromCodeType(ResultCodes resultCode){
            ResultBean bean= new ResultBean();
            bean.setCode(resultCode.getCode());
            bean.setMsg(resultCode.getMessage());
            return  bean;
        }
        /**
         * 成功通用
         * @param object
         * @return
         */
        public static ResultBean success(Object object) {
            ResultBean bean=   initFromCodeType(ResultCodes.SUCCESS);
            bean.setData(object);
            return  bean;
        }
        /**
         * 无数据成功
         * @return
         */
        public static ResultBean success() {
            return  success(null);
        }
        /**
         * 失败通用1
         * @param code
         * @param msg
         * @return
         */
        public static ResultBean fail(Integer code, String msg) {
            ResultBean bean= new ResultBean();
            bean.setCode(code);
            bean.setData(null);
            bean.setMsg(msg);
            return  bean;
        }
        /**
         * 失败通用2
         * @param resultCode
         * @return
         */
        public static ResultBean fail(ResultCodes resultCode) {
           return  initFromCodeType(resultCode);
        }
        /**
         * 失败通用3
         * @param resultCode
         * @param object
         * @return
         */
        public static ResultBean fail(ResultCodes resultCode, Object object) {
            ResultBean bean= new ResultBean();
            bean.setCode(resultCode.getCode());
            bean.setData(object);
            bean.setMsg(resultCode.getMessage());
            return  bean;
        }
        
        /**
         * 无权限访问
         * @return
         */
        public static ResultBean failForbid() {
            return initFromCodeType(ResultCodes.FORBID);
        }
    }

  • ResultCodes.java
package com.itnetschool.common.bean;

import lombok.Getter;

@Getter
public enum ResultCodes {
    SUCCESS(200, "成功"),
    NOTFOUND(404, "接口地址错误"),
    FORBID(403, "权限不足"),#更多错误枚举实例,请自定义
    ;
    private Integer code;

    private String message;


    ResultCodes(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

统一错误处理

  • 自定义 异常处理类
package com.itnetschool.common.exceptions;

import com.itnetschool.common.bean.ResultCodes;
import lombok.Getter;
@Getter
public class CommonException extends RuntimeException{

    private Integer code;

    public CommonException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public CommonException(ResultCodes resultCode) {
        super(resultCode.getMessage());
        this.code = resultCode.getCode();
    }
}
  • 通过spring ControllerAdvice构建 统一异常处理方法。更多统一异常,请根据需要补充
package com.itnetschool.common.exceptions;



import com.itnetschool.common.bean.ResultBean;
import com.itnetschool.common.bean.ResultCodes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;



@ControllerAdvice
@Slf4j
public class CommonExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultBean handle(Exception e) {

        if (e instanceof CommonException) {
            CommonException exception = (CommonException) e;
            return ResultBean.fail(exception.getCode(), exception.getMessage());
        } else if (e instanceof NoHandlerFoundException || e instanceof HttpMediaTypeNotAcceptableException) {
            return ResultBean.fail(ResultCodes.NOTFOUND);
        }else {
            e.printStackTrace();
            return ResultBean.fail(ResultCodes.UNKNOWN);
        }
    }
}

  • 注意404处理,通常404时,内置服务器Tomcat会自动拦截并生成404页面,而不被ExceptionHandler拦截到。在yml中加入如下配置,加载原来spring配置项下面
spring: #数据库连接
  resources:
    add-mappings: false #不让tomcat拦截  404。
  mvc:
    throw-exception-if-no-handler-found: true    #处理方式,抛出异常。全局异常处理才能拦截错误

完整参考demo:https://gitee.com/haimama/initproject

原文地址:https://www.cnblogs.com/mxjhaima/p/13728934.html