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界面
