[Spring Boot] Spring boot 整合mybatis、postgresql [Gradle构建项目]
[Spring Boot] Spring boot 整合mybatis、postgresql [Gradle构建项目]
依赖关系
代码语言:javascript复制下文中libs[“xxx”]的写法是全局管理依赖,具体开发时使用以下格式即可
compile(group: 'org.postgresql', name: 'postgresql', version: '42.2.5', ext: 'pom')
build.gradle:
buildscript { repositories {
maven { url = "https://plugins.gradle.org/m2/" }
maven { url = "http://maven.aliyun.com/nexus/content/groups/public/" }
jcenter()
} dependencies { classpath libs["spring-boot-gradle-plugin"]
}
}apply plugin: "idea"apply plugin: "java"apply plugin: "maven"apply plugin: "io.spring.dependency-management"apply plugin: "org.springframework.boot"group = "com.example"version = "1.0.0-SNAPSHOT"sourceCompatibility = 1.8dependencies { compile "org.springframework.boot:spring-boot-starter-web" /*分页和mapper插件*/
compile libs["pagehelper"] compile libs["mapper"] /**数据库驱动*/
compile libs["postgresql"] compile libs["mybatis-spring-boot-starter"] /*热部署*/
compile libs["spring-boot-devtools"] /*单元测试*/
testCompile libs["junit"]
testCompile "org.springframework.boot:spring-boot-starter-test"}
核心配置
代码语言:javascript复制启动类
@SpringBootApplication//开启事务@EnableTransactionManagement//Spring Boot实例扫描@ComponentScan(basePackages = "com.example")//Mapper扫描@MapperScan(basePackages = "com.example.core.**.dao")public class BootApp { public static void main(String[] args) {
SpringApplication.run(BootApp.class, args);
}}
代码语言:javascript复制application.yaml文件
server:
port: 8080spring:
datasource:
driver-class-name: org.postgresql.Driver
password: postgres
username: postgres
url: jdbc:postgresql://127.0.0.1:5433/postgres
devtools:
restart:
enabled: false#mybatis
mybatis:
type-aliases-package: com.example.core.**.model
mapper-locations: classpath*:mapper/*.xml
代码生成
- mapper、model采用mybatis-generator-core自动解析数据库生成
- gradle构建时src/main/java目录下的非.java结尾的文件不会被编译,所以需要将myabtis对应的xml文件移至resources目录,并在application.yaml文件配置路径
配置全局异常拦截
代码语言:javascript复制GlobalExceptionHandler
package com.example.config;import com.example.common.api.ApiErrorCode;import com.example.common.api.ApiException;import com.example.common.api.IErrorCode;import com.example.common.beans.ResponseJson;import lombok.extern.slf4j.Slf4j;import org.springframework.validation.BindException;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/**
* <p>
*
* </p>
*
* @author xiachaoyang
* @version V1.0
* @date 2019年01月11日 10:39
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2019年01月11日
* @modify reason: {方法名}:{原因}
* ...
*/@Slf4j@RestControllerAdvicepublic class GlobalExceptionHandler { /**
* <p>
* 自定义 REST 业务异常
* <p>
*
* @param e 异常类型
* @return
*/
@ExceptionHandler(value = Exception.class) public ResponseJson<Object> handleBadRequest(Exception e) { /*
* 业务逻辑异常
*/
if (e instanceof ApiException) {
IErrorCode errorCode = ((ApiException) e).getErrorCode(); if (null != errorCode) {
log.debug("Rest request error, {}", errorCode.toString()); return new ResponseJson().failed(errorCode);
}
log.debug("Rest request error, {}", e.getMessage()); return new ResponseJson().failed(e.getMessage());
} /*
* 参数校验异常
*/
if (e instanceof BindException) {
BindingResult bindingResult = ((BindException) e).getBindingResult(); if (null != bindingResult && bindingResult.hasErrors()) {
List<Object> jsonList = new ArrayList<>();
bindingResult.getFieldErrors().stream().forEach(fieldError -> {
Map<String, Object> jsonObject = new HashMap<>(2);
jsonObject.put("name", fieldError.getField());
jsonObject.put("msg", fieldError.getDefaultMessage());
jsonList.add(jsonObject);
}); return new ResponseJson().failed(jsonList, ApiErrorCode.FAILED);
}
} /**
* 系统内部异常,打印异常栈
*/
log.error("Error: handleBadRequest StackTrace : {}", e); return new ResponseJson().failed(e.getMessage());
}
}
代码语言:javascript复制ApiErrorCode
package com.example.common.api;/**
* <p>
* REST API 错误码
* </p>
*
* @author xiachaoyang
* @version V1.0
* @date 2019年01月11日 10:48
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2019年01月11日
* @modify reason: {方法名}:{原因}
* ...
*/public enum ApiErrorCode implements IErrorCode { /**
* 失败
*/
FAILED("0", "失败"), /**
* 成功
*/
SUCCESS("1", "成功"); private final String code; private final String msg; ApiErrorCode(final String code, final String msg) { this.code = code; this.msg = msg;
} public static ApiErrorCode fromCode(String code) {
ApiErrorCode[] ecs = ApiErrorCode.values(); for (ApiErrorCode ec : ecs) { if (ec.getCode().equalsIgnoreCase(code)) { return ec;
}
} return SUCCESS;
} @Override
public String getCode() { return code;
} @Override
public String getMsg() { return msg;
} @Override
public String toString() { return String.format(" ErrorCode:{code=%s, msg=%s} ", code, msg);
}}
代码语言:javascript复制ApiException
package com.example.common.api;/**
* <p>
*
* </p>
*
* @author xiachaoyang
* @version V1.0
* @date 2019年01月11日 10:46
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2019年01月11日
* @modify reason: {方法名}:{原因}
* ...
*/public class ApiException extends RuntimeException { /**
* 错误码
*/
private IErrorCode errorCode; public ApiException(IErrorCode errorCode) { super(errorCode.getMsg()); this.errorCode = errorCode;
} public ApiException(String message) { super(message);
} public ApiException(Throwable cause) { super(cause);
} public ApiException(String message, Throwable cause) { super(message, cause);
}`在这里插入代码片` public IErrorCode getErrorCode() { return errorCode;
}
}
代码语言:javascript复制IErrorCode
package com.example.common.api;/**
* <p>
* REST API 错误码接口
* </p>
*
* @author xiachaoyang
* @version V1.0
* @date 2019年01月11日 10:46
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2019年01月11日
* @modify reason: {方法名}:{原因}
* ...
*/public interface IErrorCode { /**
* 错误编码 0、失败 1、正常
*/
String getCode(); /**
* 错误描述
*/
String getMsg();}
代码语言:javascript复制ResponseJson
package com.example.common.beans;import com.example.common.api.IErrorCode;import lombok.Data;import lombok.experimental.Accessors;/**
* <p>
*
* </p>
*
* @author xiachaoyang
* @version V1.0
* @date 2018年12月27日 17:26
* @modificationHistory=========================逻辑或功能性重大变更记录
* @modify By: {修改人} 2018年12月27日
* @modify reason: {方法名}:{原因}
* ...
*/@Data@Accessors(chain = true)public class ResponseJson<T> { private String msg; private String code; private T data; public ResponseJson<T> failed(IErrorCode errorCode) { this.code = errorCode.getCode(); this.msg = errorCode.getMsg(); return this;
} public ResponseJson<T> failed(String errorMsg) { this.code = "-1"; this.msg = errorMsg; return this;
} public ResponseJson<T> ok(T data) { this.data = data; this.code = "0"; this.msg = "success"; return this;
} public ResponseJson<T> failed(T data, IErrorCode errorCode) { this.data = data; this.code = errorCode.getCode(); this.msg = errorCode.getMsg(); return this;
}
}
效果(json请求参数中非数字字符串无法转数字错误)