基于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); }