一、為什麼選擇SpringBoot Spring Boot是由Pivotal團隊提供的全新框架,被很多業內資深人士認為是可能改變游戲規則的新項目。早期我們搭建一個SSH或者Spring Web應用,需要非常繁瑣的步驟,比如配置web.xml,配置資料庫連接,配置事務,配置日誌,配置Tomcat,裝配 ...
一、為什麼選擇SpringBoot
Spring Boot是由Pivotal團隊提供的全新框架,被很多業內資深人士認為是可能改變游戲規則的新項目。早期我們搭建一個SSH或者Spring Web應用,需要非常繁瑣的步驟,比如配置web.xml,配置資料庫連接,配置事務,配置日誌,配置Tomcat,裝配Bean,聲明和配置切麵等等等等,如果項目過大多人協作各種冗長啰嗦的配置讓人煩不勝煩,這麼多年下來,給人一種Java就是大型配置文件的感覺。
SpringBoot的設計目的是用來簡化新Spring應用的初始搭建以及開發過程,吸引更多開發者的最大亮點之一是集成了自動配置的魔力。SpringBoot的四個主要新特性如下:
1、Spring Boot Starter:它將常用的依賴分組進行了整合, 將其合併到一個依賴中, 這樣就可以一次性添加到項目的Maven或Gradle構建中;Spring Boot通過提供眾多起步依賴降低項目依賴的複雜度。起步依賴本質上是一個Maven項目對象模型(Project Object Model, POM),定義了對其他庫的傳遞依賴,這些東西加在一起即支持某項功能。很多起步依賴的命名都暗示了它們提供的某種或某類功能。Spring Boot經過了足夠的測試,確保引入的全部依賴都能相互相容。這是一種解脫,只需指定起步依賴,不用擔心自己需要維護哪些庫,也不必擔心它們的版本。
2、自動配置:Spring Boot的自動配置特性利用了Spring 4對條件化配置的支持, 合理地推測應用所需的bean並自動化配置它們;最後, Spring Boot沒有引入任何形式的代碼生成,而是利用了Spring 4的條件化配置特性,以及Maven和Gradle提供的傳遞依賴解析,以此實現Spring應用程式上下文里的自動配置。簡而言之, Spring Boot的自動配置是一個運行時(更準確地說,是應用程式啟動時)的過程,考慮了眾多因素,才決定Spring配置應該用哪個,不該用哪個。每當應用程式啟動的時候, Spring Boot的自動配置都要做將近200個這樣的決定,涵蓋安全、集成、持久化、 Web開發等諸多方面。所有這些自動配置就是為了儘量不讓你自己寫配置。
3、命令行介面(Command-line interface, CLI):Spring Boot的CLI發揮了Groovy編程語言的優勢, 並結合自動配置進一步簡化Spring應用的開發;
4、Actuator: 它為Spring Boot應用添加了一定的管理特性。
常見的搭建一個SpringBoot應用只要如下幾步:
1、打開http://start.spring.io/
2、點擊“Switch to the full version,選擇Java版本,如1.8,選擇好構建工具,如Maven或Gradle
4、點擊Generate Project下載項目壓縮包
5、解壓後,使用eclipse或者intellij idea,導入項目即可
當然,對於經驗豐富的老鳥,不需要打開網頁再下載解壓導入文件那麼多步驟,通過Idea也可以一步一步構造SpringBoot項目。
二、工程結構
官方生成的SpringBoot項目,預設結構說明:
1、src/main/java 程式開發以及主程式入口
2、src/main/resources 配置文件
3、src/test/java 測試程式
src/main/java根目錄下麵,有如下Java類和包:
1、Application.java 應用程式入口,包括一個靜態main方法,可以做一些框架配置,比如mybatis、swagger等
2、domain目錄主要用於數據訪問實體(DataObject)與數據訪問層(Repository)
3、service目錄主要是業務邏輯相關的服務介面和實現
4、controller負責頁面訪問控制,對外暴露API
當然,我們需要參考成熟的項目結構或者根據個人經驗來改造項目結構,本文的SpringBootDemo為了方便僅做簡單調整,項目結構如下:
主要包說明:
公共模塊
1、common:公共類,如枚舉,常量、業務無關的通用公共實體等
2、util:常用實用的幫助類,如反射、字元串、集合、枚舉、正則、緩存、隊列等
3、config:自定義的配置項,可從配置文件讀取
表現層
1、controller:負責頁面訪問控制,對外暴露Rest API介面
數據訪問層
1、domain:數據對象實體DO,通常和數據表、視圖或其他業務對象一一對應
2、dao:數據訪問對象,本文demo選擇比較熟悉的mybatis作為ORM工具
業務邏輯層
1、service:服務 contract是介面,impl是服務實現
2、entity:實體 vo是服務可對外公開的實體;dto是數據傳輸對象,可在服務間傳遞;qo:查詢對象,可以認為是查詢條件的封裝
本文demo沒有寫dto和qo示例,很多中小型項目,entity其實是非常混亂的,實體設計和分層抽象有問題,有時候直接影響到業務邏輯複雜程度。
關於工程結構,尤其是應用分層和領域實體抽象(數據訪問對象DO和顯示層對象VO等),強烈推薦大家參考<<阿裡巴巴Java開發手冊>>終極版本的工程結構一章。
三、MyBatis使用
Maven依賴:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency>View Code
資料庫驅動:
MySQL:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency>View Code
SQLServer:
<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>6.4.0.jre8</version> </dependency>View Code
隆重公告,微軟Microsoft JDBC Driver For SQL Server已發佈到maven中央倉庫,本文的demo選擇的是SQLServer,主要是MySQL很多人都寫了,資料太充足,不如試試不同的風格,而且我在前廠寫的第一個線上SpringBoot應用也是訪問SQLServer,demo就哪個好舉例就用哪個了。
配置文件中的配置:
## MYSQL數據源配置 #spring.datasource.url=jdbc:mysql://localhost:3306/springbootdb?useUnicode=true&characterEncoding=utf8 #spring.datasource.username=root #spring.datasource.password=123456 #spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## MSSQL數據源配置 spring.datasource.url=jdbc:sqlserver://localhost;databaseName=TestDB spring.datasource.username=sa spring.datasource.password=123456 spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver spring.jpa.show-sql=true spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect #spring.jpa.hibernate.ddl-auto = create-drop ## Mybatis 配置 mybatis.typeAliasesPackage=com.power.demo.domain mybatis.mapperLocations=classpath:mapper/*.xmlView Code
Mapper配置:
<?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.power.demo.dao.GoodsDao"> <resultMap id="BaseResultMap" type="com.power.demo.domain.GoodsDO"> <result column="GoodsId" property="goodsId"/> <result column="GoodsCode" property="goodsCode"/> <result column="GoodsName" property="goodsName"/> <result column="GoodsType" property="goodsType"/> <result column="CreateTime" property="createTime"/> <result column="Disabled" property="disabled"/> </resultMap> <parameterMap id="Goods" type="com.power.demo.domain.GoodsDO"/> <sql id="Base_Column_List"> GoodsId,GoodsCode,GoodsName,GoodsType,CreateTime,Disabled </sql> <select id="findGoodsByGoodsId" resultType="GoodsDO" parameterType="java.lang.String"> SELECT <include refid="Base_Column_List"/> FROM Goods WITH(NOLOCK) WHERE 1=1 AND Disabled=0 AND GoodsId = #{goodsId} </select> <select id="findGoodsByGoodsCode" resultType="GoodsDO" parameterType="java.lang.String"> SELECT <include refid="Base_Column_List"/> FROM Goods WITH(NOLOCK) WHERE 1=1 AND Disabled=0 AND GoodsCode = #{goodsCode} </select> <select id="findGoodsByGoodsType" resultType="GoodsDO" parameterType="java.lang.Integer"> SELECT <include refid="Base_Column_List"/> FROM Goods WITH(NOLOCK) WHERE 1=1 AND Disabled=0 AND GoodsType = #{goodsType} </select> <select id="findAllGoods" resultType="GoodsDO"> SELECT <include refid="Base_Column_List"/> FROM Goods WITH(NOLOCK) WHERE 1=1 </select> <insert id="insertGoods" parameterMap="Goods"> INSERT INTO Goods (GoodsId,GoodsCode,GoodsName,GoodsType,CreateTime,Disabled) VALUES(#{goodsId},#{goodsCode},#{goodsName},#{goodsType},#{createTime},#{disabled}) </insert> <insert id="updateGoods" parameterMap="Goods"> UPDATE Goods SET Disabled=#{disabled} WHERE GoodsId=#{goodsId} </insert> <insert id="deleteGoods" parameterType="java.lang.String"> DELETE FROM Goods WHERE GoodsId=#{goodsId} </insert> </mapper>View Code
最後,在應用程式入口,添加一行註解:
// mapper 介面類掃描包配置 @MapperScan("com.power.demo.dao") public class Application { }
本文demo只提供了簡單的CRUD,但是常見的開發還有很多東西要寫。比如:
如何做多庫配置,如何動態拼接執行複雜SQL,如何批量插入,如何拿到運行時SQL語句,如何使用存儲過程,如何進行數據緩存、如何使用事務等。
這些遺留內容希望有心的你慢慢去發掘嘗試了。
推薦MyBatis代碼生成器:MyBatis Generator
四、API文檔描述
使用應用廣泛的Swagger,生成API文檔。
Maven中添加依賴:
<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>View Code
需要在應用程式入口Application裡面加一行註解:
@EnableSwagger2 public class Application { }
不要忘了Api說明和實體說明配置,demo提供了完整示例。
五、單元測試
使用Junit進行單元測試
/** * Created by JeffWong. */ @RunWith(SpringRunner.class) @SpringBootTest public class CommonTests { @Test public void testGoodsTypeEnum() throws Exception { GoodsType goodsType = GoodsType.Discount; System.out.println(GoodsType.Normal.ordinal());//0 System.out.println(GoodsType.Discount.ordinal());//1 System.out.println(goodsType.getCode()); System.out.println(goodsType.getDescription()); Assert.isTrue(goodsType.getCode() == 1024, "折扣商品Code為1024"); } }View Code
如果需要單元測試的方法需要配置文件,那麼test下也要有resources目錄用於存放資源文件。
本文demo提供了完整的各層單元測試方法,大家可以參考下。
總結:使用SpringBoot全家桶,你可以快速上手開發Java的REST介面應用,配合Java8+的相關新特性,寫Java也越來越省心(雖然Java8的lamda比較難受,Checked Exception層層感染有點受不了,Date非常不好用-_-),聽說Java10要有var,估計還可以少寫很多代碼,而且VS也要支持Java了(不是J#),作為有豐富開發經驗的.NET開發者,也就更加有嘗試的衝動了。
最後提供demo下載。
參考:
<<阿裡巴巴Java開發手冊>>
<<Spring in Action>>
<<Spring Boot in Action>>
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
https://www.jianshu.com/u/6a622d516e32