MP实战系列(八)之SpringBoot+Swagger2
SpringBoot一个原则,爱好编程的朋友们都知道,那就是"习惯优于配置"。
今天一上来主要说的还是代码,个人比较喜欢来的实战系列的,不过有的时候还是比较偏重于理论,理论是造轮子的基础之一,尽管前人先辈们或者其他编程界的大牛们已经为我们造了不少轮子,大牛们造的轮子在广义上是比较通用的,例如jeecg的插件式开发等。
不过对于项目需求而言,有些时候不一定开源的就一定可以复用,有些时候我们必须要在此创新。
记得我一个朋友,他们公司给他的一个业务是测试框架,该测试框架必须匹配公司各个业务场景,他在开源上找了不少项目,但是发现还是不行,有些只能解解燃眉之急,但是风险不可控。所以我这位朋友他决定为了更好的匹配公司的业务,他决定自己造轮子,不过当然还是站在前人的肩膀上。他用技术还是Java的反射和Google的一个技术,记得我跟我提过,不过此时我不记得了。
最终他还是成功造轮子,在这里我想表达的不是,造轮子,对于现有的轮子,如果我要采用必先满足我个人这些要求:
(1)文档丰富;
(2)开源项目活跃;
(3)风险可控;
(4)学习成本低;
当然最主要的是前三项,当然如果是开发赶进度的话,第四项不得不考虑进来。
毕竟一项技术,一个团队再用,如果学习成本毕竟高的话,到时项目遇到各种各样的问题,光解决问题就会花不少时间。
前三项就不用特别说了,文档丰富,例如Spring文档就很丰富。活跃,项目活跃至少可以和开源项目的开发人员进行交流。风险可控,对于企业而言,风险不可控意味着非常大的隐患,特别是金融方面的。
闲话不多说了,下面贴代码:
一、导入依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.blog</groupId>
<artifactId>blog001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent> <repositories>
<!--阿里云仓库-->
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<!--快照版本使用,正式版本无需添加此仓库-->
<repository>
<id>snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
</repositories> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<mybatis-plus-boot-starter.version>2.1.9</mybatis-plus-boot-starter.version>
<mybatisplus.version>2.1.8</mybatisplus.version>
<HikariCP.version>2.4.13</HikariCP.version>
<fastjson.version>1.2.39</fastjson.version>
<druid.version>1.1.0</druid.version>
</properties> <dependencies> <!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency> <!-- shiro+spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- swagger-ui相关 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
</dependency> <!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.19</version>
</dependency> <!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency> <dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java7</artifactId>
<version>${HikariCP.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- mybatis-plus begin -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
<exclusions>
<exclusion>
<artifactId>tomcat-jdbc</artifactId>
<groupId>org.apache.tomcat</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- mybatis-plus end --> <!-- JUnit test dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency> <!-- Code generator test sample-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、编写Java代码
Application.java 启动类
package com.blog.springboot; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement; @EnableTransactionManagement
@SpringBootApplication
public class Application { protected final static Logger logger = LoggerFactory.getLogger(Application.class); public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
logger.info("Application is success!"); } }
MyMetaObjectHandler.java
package com.blog.springboot; import com.baomidou.mybatisplus.mapper.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* 注入公共字段自动填充,任选注入方式即可
*/
//@Component
public class MyMetaObjectHandler extends MetaObjectHandler { protected final static Logger logger = LoggerFactory.getLogger(Application.class); @Override
public void insertFill(MetaObject metaObject) {
logger.info("新增");
} @Override
public void updateFill(MetaObject metaObject) {
logger.info("更新");
}
}
MybatisPlusConfig.java(扫描Mapper文件)
package com.blog.springboot.config; import java.util.ArrayList;
import java.util.List; import com.baomidou.mybatisplus.incrementer.H2KeyGenerator;
import com.baomidou.mybatisplus.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.mapper.ISqlInjector;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.mapper.MetaObjectHandler; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.plugins.parser.ISqlParser;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantHandler;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantSqlParser;
import com.blog.springboot.MyMetaObjectHandler; import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue; @Configuration
@MapperScan("com.blog.springboot.mapper*")
public class MybatisPlusConfig { /**
* mybatis-plus SQL执行效率插件【生产环境可以关闭】
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
return new PerformanceInterceptor();
} @Bean
public MetaObjectHandler metaObjectHandler(){
return new MyMetaObjectHandler();
} /**
* 注入主键生成器
*/
@Bean
public IKeyGenerator keyGenerator(){
return new H2KeyGenerator();
} /**
* 注入sql注入器
*/
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
} }
Swagger2.java
package com.blog.springboot.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration
@EnableSwagger2
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.blog.springboot"))
.paths(PathSelectors.any())
.build();
} private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("博客系统")
.description("世界因编程而美好,编程改变世界")
.termsOfServiceUrl("http://520.cn")
.contact("yy")
.version("1.0")
.build();
} }
WebConfig.java
package com.blog.springboot.config; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver; /**
* <p>
* WEB 初始化相关配置
* </p>
*/
@ControllerAdvice
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter { @Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/static/** 访问都映射到classpath:/static/ 目录下
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
}
UserEntity.java
package com.blog.springboot.entity; import java.io.Serializable; import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType; /**
* <p>
*
* </p>
*
* @author youcong123
* @since 2018-05-19
*/
@TableName("user")
public class UserEntity extends Model<UserEntity> { /**
* 用户ID
*/
@TableId(value = "user_id", type = IdType.AUTO)
private Integer user_id;
/**
* 用户名
*/
private String username;
/**
* 性别
*/
private Integer sex;
/**
* 电话
*/
private String phone;
/**
* 密码
*/
private String password;
/**
* 等级
*/
private Integer level;
/**
* 用户创建时间
*/
@TableField("create_time")
private String createTime;
/**
* 邮箱
*/
private String email;
/**
* 登录标识
*/
private Integer logo;
/**
* 登录时间
*/
@TableField("login_time")
private String loginTime; public Integer getUserId() {
return user_id;
} public void setUserId(Integer user_id) {
this.user_id = user_id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Integer getSex() {
return sex;
} public void setSex(Integer sex) {
this.sex = sex;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public Integer getLevel() {
return level;
} public void setLevel(Integer level) {
this.level = level;
} public String getCreateTime() {
return createTime;
} public void setCreateTime(String createTime) {
this.createTime = createTime;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public Integer getLogo() {
return logo;
} public void setLogo(Integer logo) {
this.logo = logo;
} public String getLoginTime() {
return loginTime;
} public void setLoginTime(String loginTime) {
this.loginTime = loginTime;
} @Override
public String toString() {
return "User{" +
"userId=" + user_id +
", username=" + username +
", sex=" + sex +
", phone=" + phone +
", password=" + password +
", level=" + level +
", createTime=" + createTime +
", email=" + email +
", logo=" + logo +
", loginTime=" + loginTime +
"}";
} @Override
protected Serializable pkVal() {
// TODO Auto-generated method stub
return this.user_id;
}
}
UserDao.java
package com.blog.springboot.mapper; import com.blog.springboot.entity.UserEntity;
import com.baomidou.mybatisplus.mapper.BaseMapper; /**
* <p>
* Mapper 接口
* </p>
*
* @author youcong123
* @since 2018-05-19
*/
public interface UserDao extends BaseMapper<UserEntity> { }
UserService.java
package com.blog.springboot.service; import com.blog.springboot.entity.UserEntity;
import com.baomidou.mybatisplus.service.IService; /**
* <p>
* 服务类
* </p>
*
* @author youcong123
* @since 2018-05-19
*/
public interface UserService extends IService<UserEntity> { }
UserServiceImpl.java
package com.blog.springboot.service.impl; import com.blog.springboot.entity.UserEntity;
import com.blog.springboot.mapper.UserDao;
import com.blog.springboot.service.UserService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; /**
* <p>
* 服务实现类
* </p>
*
* @author youcong123
* @since 2018-05-19
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService { }
UserController.java
package com.blog.springboot.controller; import java.util.List;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSON;
import com.blog.springboot.entity.UserEntity;
import com.blog.springboot.service.UserService; import io.swagger.annotations.ApiOperation; /**
* <p>
* 前端控制器
* </p>
*
* @author youcong123
* @since 2018-05-19
*/
@Controller
@RequestMapping("/user")
public class UserController { @GetMapping(value="/test")
public String index() { return "index"; } @Autowired
private UserService userService;
@ApiOperation(value="获取用户列表", notes="")
@GetMapping(value="/list",produces="application/json;charset=utf-8")
@ResponseBody
public String list(Map<String,Object> map) {
List<UserEntity> list = userService.selectList(null);
map.put("list", list);
return JSON.toJSONString(map); } }
UserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.blog.springboot.mapper.UserDao"> <!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.blog.springboot.entity.UserEntity">
<id column="user_id" property="user_id" />
<result column="username" property="username" />
<result column="sex" property="sex" />
<result column="phone" property="phone" />
<result column="password" property="password" />
<result column="level" property="level" />
<result column="create_time" property="createTime" />
<result column="email" property="email" />
<result column="logo" property="logo" />
<result column="login_time" property="loginTime" />
</resultMap> <!-- 通用查询结果列 -->
<sql id="Base_Column_List">
user_id AS userId, username, sex, phone, password, level, create_time AS createTime, email, logo, login_time AS loginTime
</sql> </mapper>
三、编写配置文件
application.yml
#app
server:
port: 8080 spring:
devtools:
restart:
enabled: false datasource:
url: jdbc:mysql://localhost:3306/blog?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: root
password: 1234
db-name: blog
filters: log4j,wall,mergeStat1 #mybatis
mybatis-plus:
mapper-locations: classpath:/mapper/*Dao.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.blog.springboot.entity
global-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: 2
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 2
#驼峰下划线转换
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true #逻辑删除配置(下面3个配置)
logic-delete-value: 0
logic-not-delete-value: 1
#自定义sql注入器,不在推荐使用此方式进行配置,请使用自定义bean注入
sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
#自定义填充策略接口实现,不在推荐使用此方式进行配置,请使用自定义bean注入
meta-object-handler: com.blog.springboot.MyMetaObjectHandler
#自定义SQL注入器
#sql-injector: com.baomidou.springboot.xxx
# SQL 解析缓存,开启后多租户 @SqlParser 注解生效
sql-parser-cache: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
#logging
logging:
level: warn
四、添加swagger-ui相关界面
swagger-ui界面可以去github下载,地址为:https://github.com/swagger-api/swagger-ui
我个人下载的是如上红色标记处,最新版
下载完毕后将其解压,并在dist目录的所有文件放置在static文件夹下的swagger-ui文件夹下
五、启动Application,访问
swagger界面
MP实战系列(八)之SpringBoot+Swagger2的更多相关文章
- MP实战系列(七)之集成springboot
springboot是现在比较流行的微服使用的框架,springboot本质上就是将spring+springmvc+mybatis零配置化,基本上springboot的默认配置符合我们的开发.当然有 ...
- MP实战系列(九)之集成Shiro
下面示例是在之前的基础上进行的,大家如果有什么不明白的可以参考MP实战系列的前八章 当然,同时也可以参考MyBatis Plus官方教程 建议如果参考如下教程,使用的技术为spring+mybatis ...
- MP实战系列(二)之集成swagger
其实与spring+springmvc+mybatis集成swagger没什么区别,只是之前写的太不好了,所以这次决定详细写. 提到swagger不得不提rest,rest是一种架构风格,里面有对不同 ...
- MP实战系列(十四)之分页使用
MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...
- MP实战系列(十二)之封装方法详解(续二)
继续MP实战系列(十一)之封装方法详解(续一)这篇文章之后. 此次要讲的是关于查询. 查询是用的比较多的,查询很重要,好的查询,加上索引如鱼得水,不好的查询加再多索引也是无济于事. 1.selectB ...
- MP实战系列(十)之SpringMVC集成SpringFox+Swagger2
该示例基于之前的实战系列,如果公司框架是使用JDK7以上及其Spring+MyBatis+SpringMVC/Spring+MyBatis Plus+SpringMVC可直接参考该实例. 不过建议最好 ...
- MP实战系列(三)之实体类讲解
首先说一句,mybatis plus实在太好用了! mybaits plus的实体类: 以我博客的用户类作为讲解 package com.blog.entity; import com.baomido ...
- ElasticSearch实战系列八: Filebeat快速入门和使用---图文详解
前言 本文主要介绍的是ELK日志系统中的Filebeat快速入门教程. ELK介绍 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是 ...
- MP实战系列(十八)之XML文件热加载
你还在为每次修改XML文件中的SQL重新启动服务器或者是等待几分钟而烦恼吗? 配置了热加载即可解决你的这个问题. 这就是XML文件热加载的目的,减少等待时间成本,提高开发效率. SSM框架配置(Spr ...
随机推荐
- 撩课-Web大前端每天5道面试题-Day29
1.https协议的优点? 使用HTTPS协议可认证用户和服务器, 确保数据发送到正确的客户机和服务器: HTTPS协议是由SSL+HTTP协议构建的可进行加密传输. 身份认证的网络协议,要比http ...
- video视频在本地可以播放,在服务器上不可以播放
今天遇到一个比较坑的问题,视频在本地可以播放,然后放到服务器上面就播放不了,原因是因为服务器上面不支持mp4的播放,下面看解决办法.1.首先进入IIS(Internet Information Ser ...
- 开源项目管理工具KanBoard
KanBoard是一个很好用的项目管理软件,地址点此.它以网页形式存储在服务器或者本地,支持多标签.多项目.多用户和多种显示方式.编辑方式上支持markdown.它还提供多角度可视化的项目统计分析. ...
- 如何获取listview里面的edittext或者RadioGroup的值,涉及到引发的混乱现象
最近要实现从数据库读数据,该数据对应listview的item布局里面的RadioButton值,并且item布局里面还有EditText的控件. 如何将每一条对应的listview对应值获取出来呢? ...
- 原生JSON解析
原生JSON解析 JSONObject:JSON数据封装对象JSONArray:JSON数据封装数组 布局: <?xml version="1.0" encoding=&qu ...
- Android网络编程系列之HTTP协议原理总结
前言 作为搞移动开发的我们,免不了与网络交互打交道.虽然市面上很多开源库都封装的比较到位,我们实现网络访问也轻车熟路.但还是十分有必要简要了解一下其中的原理,以便做到得心应手,也是通往高级开发工程师甚 ...
- 【jdk源码1】TreeMap源码学习
这是看过的第一个jdk源码(从立下目标以来):TreeMap.说实话断断续续的看了有好几天了,我觉得我犯了一个错误,就像一开始说的那样,我打算完完全全看懂TreeMap关于红黑树的实现方式,后来我想了 ...
- 机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据
机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据 关键字:PCA.主成分分析.降维作者:米仓山下时间:2018-11-15机器学习实战(Ma ...
- python自学——文件修改
#如何修改文件,我们知道文件因为在磁盘上已经有储存了,后面要更新或修改,只能在在原来文件后面追加使用f=open("wenjian_name","r+",enc ...
- jQuery为元素设置css的问题
例子: 有如下的html代码 对文本框设置字体大小为20px ,即font-size:20px 首先会想到如下: $('input').css({font-size:'20px'}); 由于属性不能使 ...