[Spring Boot] Spring boot 整合mybatis、postgresql [Gradle构建项目]
依赖关系
下文中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.8
dependencies {
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"
}
核心配置
启动类
@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);
}
}
application.yml文件
server:
port: 8080
spring:
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文件配置路径
配置全局异常拦截
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
@RestControllerAdvice
public 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());
}
}
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);
}
}
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;
}
}
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();
}
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请求参数中非数字字符串无法转数字错误)
更多
扫码关注或搜索架构探险之道
获取最新文章,不积跬步无以至千里,坚持每周一更,坚持技术分享^_^
!