Spring全家桶系列--SpringBoot漸入佳境

1.Lombok插件

對于開發(fā)人員來說耕餐,我要解釋這個什么意思肠缔,你肯定也是一知半解哼转,直接來代碼解釋吧

1.1 代碼演示

package com.example.entity;

public class Area {

? ?private Integer id;

? ?private Integer postalcode;

? ?private String address;

? ?private Integer type;

? ?public Integer getId() {

? ? ? ?return id;

? ?}

? ?public void setId(Integer id) {

? ? ? ?this.id = id;

? ?}

? ?public Integer getPostalcode() {

? ? ? ?return postalcode;

? ?}

? ?public void setPostalcode(Integer postalcode) {

? ? ? ?this.postalcode = postalcode;

? ?}

? ?public String getAddress() {

? ? ? ?return address;

? ?}

? ?public void setAddress(String address) {

? ? ? ?this.address = address == null ? null : address.trim();

? ?}

? ?public Integer getType() {

? ? ? ?return type;

? ?}

? ?public void setType(Integer type) {

? ? ? ?this.type = type;

? ?}

}

使用了Lombok之后

package com.example.entity;

import lombok.Data;

@Data

public class Area {

? ?private Integer id;

? ?private Integer postalcode;

? ?private String address;

? ?private Integer type;

}

以上兩者的效果是相同的,現(xiàn)在我們知道它是干嘛的了,下面開始使用吧

1.2 安裝Lombok

在Intellij IDEA中安裝lombok插件

安裝完重啟IDEA

打開設(shè)置找到上述并勾選,然后在build.gradle文件中增加

//讓gradle具有內(nèi)置的compileOnly范圍煮纵,可用于告訴gradle僅在編譯期間添加lombok

compileOnly 'org.projectlombok:lombok:1.18.4'

刷新Gradle之后就可以了

然后隨意找個測試類行疏,例如如下

package com.example.demo;

import com.example.entity.Area;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)

@SpringBootTest

public class DemoApplicationTests {

? ?@Test

? ?public void contextLoads() {

? ? ? ?Area area=new Area();

? ? ? ?//這里可以有g(shù)et方法證明就ok 可以使用了

? ? ? ?area.getType();

? ?}

}

2.PageHelper分頁插件

萌新:小哥酿联,我很苦惱分頁這個功能怎么辦夺巩?

小哥:那不是可以寫好一個邏輯直接復制嗎柳譬?

萌新:那也需要很多行代碼美澳,導致了需要在mapper以及業(yè)務(wù)層做很多無用功

小哥:哈哈摸航,那我來告訴你一款分頁插件酱虎,解決你的困擾

首先擂涛,在build.gradle中引入依賴

/** buildscript中的聲明是gradle腳本自身需要使用的資源撒妈。

* ?可以聲明的資源包括依賴項狰右、第三方插件、maven倉庫地址等

*/

buildscript {

? ?ext {

? ? ? ?springBootVersion = '2.0.1.RELEASE'

? ? ? ?mysqlVersion = '5.1.39'

? ?}

? ?repositories {

? ? ? ?//使用國內(nèi)源下載依賴

? ? ? ?maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }

? ?}

? ?dependencies {

? ? ? ?classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")

? ?}

}

// 應用Java插件

apply plugin: 'java'

//讓工程支持IDEA的導入

apply plugin: 'idea'

apply plugin: 'org.springframework.boot'

group = 'com.example'

version = '0.0.1-SNAPSHOT'

sourceCompatibility = 1.8

//build.gradle文件中直接聲明的依賴項、倉庫地址等信息是項目自身需要的資源附鸽。

repositories {

? ?maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }

? ?mavenCentral()

}

/**

* 在gradle里坷备,對依賴的定義有6種

* compile, runtime, testCompile, testRuntime, providedCompile,providedRuntime

* compile:需要引用這個庫才能進行編譯工作

* testRuntime : 測試依賴范圍

* 其他的了解:http://shmilyaw-hotmail-com.iteye.com/blog/2345439

*/

dependencies {

? ?compile('org.springframework.boot:spring-boot-starter-web:2.0.1.RELEASE')

? ?compile('com.alibaba:druid:1.0.29')

? ?testCompile('org.springframework.boot:spring-boot-starter-test:2.0.1.RELEASE')

? ?//這里的版本可以在上述定義

? ?compile 'mysql:mysql-connector-java:5.1.39'

? ?compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'

? ?//讓gradle具有內(nèi)置的compileOnly范圍省撑,可用于告訴gradle僅在編譯期間添加lombok

? ?compileOnly 'org.projectlombok:lombok:1.18.4'

? ?//分頁插件

? ?compile 'com.github.pagehelper:pagehelper-spring-boot-starter:1.2.10'

}

這里同時也將SpringBoot升到了2.0竟秫,具體的新功能研究后會總結(jié)一下的

pagehelper這個插件估計和Spring1.5.x的版本有兼容性問題

上面的配置都是我測試好的肥败,直接替換然后重新刷新Gradle

上篇的自動生成的mapper.xml文件中無查詢?nèi)康姆椒ㄣ堤幔@里補上一下

? ?<select id="selectAreaAll" resultMap="BaseResultMap">

? ? ? ?select

? ? ? ?<include refid="Base_Column_List" />

? ? ? ?from area

? ?</select>

然后在dao借口插入方法接口 AreaMapper.java

package com.example.dao;

import com.example.entity.Area;

import java.util.List;

public interface AreaMapper {

? ?int deleteByPrimaryKey(Integer id);

? ?int insert(Area record);

? ?int insertSelective(Area record);

? ?Area selectByPrimaryKey(Integer id);

? ?int updateByPrimaryKeySelective(Area record);

? ?int updateByPrimaryKey(Area record);

? ?/**

? ? * 查詢?nèi)?/p>

? ? * @return

? ? */

? ?List<Area> selectAreaAll();

}

AreaService.java

package com.example.service;

import com.example.entity.Area;

import java.util.List;

/**

* 這里給dao層的代碼拷貝過來先使用

* created by cfa ?2018-11-08 下午 9:56

**/

public interface AreaService {

? ?int deleteByPrimaryKey(Integer id);

? ?int insert(Area record);

? ?int insertSelective(Area record);

? ?Area selectByPrimaryKey(Integer id);

? ?int updateByPrimaryKeySelective(Area record);

? ?int updateByPrimaryKey(Area record);

? ?List<Area> selectAreaAll(Integer pageNum,Integer pageSize);

}

上述接口的實現(xiàn)類加上 AreaServiceImpl.java

? ?/**

? ? * ?分頁核心代碼

? ? * @param pageNum

? ? * @param pageSize

? ? * @return

? ? */

? ?@Override

? ?public List<Area> selectAreaAll(Integer pageNum,Integer pageSize) {

? ? ? ?//這個要在你的查詢之前加哦

? ? ? ?PageHelper.startPage(pageNum,pageSize);

? ? ? ?//這里直接查詢?nèi)烤托辛伺耍猪摬寮婺阕龇猪摴那矡o需擔心性能問題,會自動補上limit的

? ? ? ?List<Area> areaList=areaMapper.selectAreaAll();

? ? ? ?return areaList;

? ?}

控制層調(diào)用 AreaController.java

package com.example.controller;

import com.example.entity.Area;

import com.example.service.AreaService;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController

@RequestMapping("area")

public class AreaController {

? ?private final AreaService areaService;

? ?@Autowired

? ?public AreaController(AreaService areaService) {

? ? ? ?this.areaService = areaService;

? ?}

? ?/**

? ? * 這里的@RequestParam(name = "pagesize",required = false,defaultValue = "10")

? ? * -name 為傳輸時為接受key為pagesize的參數(shù)

? ? * -required 為是否為必須傳輸?shù)膮?shù)

? ? * -default 就是如果沒有接收到值 就給予默認值

? ? * @param pageNum

? ? * @param pageSize

? ? * @return

? ? */

? ?@RequestMapping("query")

? ?public List<Area> areaList(@RequestParam(name = "pagenum",required = false,defaultValue = "1") Integer pageNum,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @RequestParam(name = "pagesize",required = false,defaultValue = "10") Integer pageSize){

? ? ? ?return areaService.selectAreaAll(pageNum,pageSize);

? ?}

}

然后在IDEA中啟動DemoApplication啟動類

用postman進行測試

postman下載地址:

https://www.cnblogs.com/wangfeng520/p/5892125.html

postman是一款可以用測試你接口的軟件,推薦花個半個小時來熟悉下

到這里已經(jīng)可以了

如果你的有問題,在我github有代碼慎陵,或者百度下錯誤席纽,因為每個人電腦的java版本不同润梯,環(huán)境不同

3.API接口返回統(tǒng)一化

現(xiàn)在的很多項目都是前后端分離的項目,所以后臺人員返回的參數(shù)參差不齊寇钉,每次對接都需要去交流一下扫倡,造成開發(fā)效率很低竟纳。

例如锥累,一個操作更新成功,后臺甲可能就返回給前臺一個1卖哎,而乙返回一個Map格式亏娜,假如批量更新呢蹬挺,返回的有時候不止是1了巴帮,所以接口返回統(tǒng)一化很重要虐秋。

萌新:那小哥肢簿,我又不是負責人池充,怎么統(tǒng)一呢

小哥:最少你自己用了之后返回的API的格式是固定的收夸,前臺很好拿數(shù)據(jù)

萌新:好的,好的開發(fā)規(guī)范厘灼,人人有責

小哥:和你說下阿里Java開發(fā)規(guī)范文檔可以看下设凹。

文檔地址:https://files.cnblogs.com/files/han-1034683568/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%E7%BB%88%E6%9E%81%E7%89%88v1.3.0.pdf

萌新:收到!

PageResultBean.java

package com.example.beans;

import com.github.pagehelper.PageInfo;

import lombok.Getter;

import java.io.Serializable;

/*

* description : 分頁API統(tǒng)一返回的bean

* @return

* @time 2018-10-15 下午 9:29 根據(jù)曉風輕的ResultBean修改來的

**/

@Getter

public class PageResultBean<T> extends ResultBean<T> implements Serializable {

? ?// 總記錄數(shù)

? ?private long totalRecord;

? ?//總頁數(shù)

? ?private int pageCount;

? ?//當前頁碼

? ?private int pageNo;

? ?//當前頁的記錄數(shù)量

? ?private int pageSize;

? ?public PageResultBean(PageInfo<T> pageInfo) {

? ? ? ?super.setData((T) pageInfo.getList());

? ? ? ?this.setPageNo(pageInfo.getPageNum())

? ? ? ? ? ? ? ?.setPageSize(pageInfo.getPageSize())

? ? ? ? ? ? ? ?.setPageCount(pageInfo.getPages())

? ? ? ? ? ? ? ?.setTotalRecord(pageInfo.getTotal());

? ?}

? ?public PageResultBean setTotalRecord(long totalRecord) {

? ? ? ?this.totalRecord = totalRecord;

? ? ? ?return this;

? ?}

? ?public PageResultBean setPageCount(int pageCount) {

? ? ? ?this.pageCount = pageCount;

? ? ? ?return this;

? ?}

? ?public PageResultBean setPageNo(int pageNo) {

? ? ? ?this.pageNo = pageNo;

? ? ? ?return this;

? ?}

? ?public PageResultBean setPageSize(int pageSize) {

? ? ? ?this.pageSize = pageSize;

? ? ? ?return this;

? ?}

? ?@Override

? ?public String toString() {

? ? ? ?return "PageResultBean{" +

? ? ? ? ? ? ? ?"totalRecord=" + totalRecord +

? ? ? ? ? ? ? ?", pageCount=" + pageCount +

? ? ? ? ? ? ? ?", pageNo=" + pageNo +

? ? ? ? ? ? ? ?", pageSize=" + pageSize +

? ? ? ? ? ? ? ?'}';

? ?}

? ?@Override

? ?public PageResultBean setMsg(String msg) {

? ? ? ?super.setMsg(msg);

? ? ? ?return this;

? ?}

? ?@Override

? ?public PageResultBean setCode(int code) {

? ? ? ?super.setCode(code);

? ? ? ?return this;

? ?}

? ?@Override

? ?public PageResultBean setData(T data) {

? ? ? ?super.setData(data);

? ? ? ?return this;

? ?}

}

附上曉風輕所著的ResultBean(略有修改) ResultBean.java

package com.example.beans;

import lombok.Data;

import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data

@NoArgsConstructor

public class ResultBean<T> implements Serializable {

? ?private static final long serialVersionUID = 1L;

? ?public static final int NO_LOGIN = -1;

? ?public static final int SUCCESS = 1;

? ?public static final int FAIL = 0;

? ?public static final int NO_PERMISSION = 2;

? ?public static final int USERNAME_EXIST = -909;

? ?private String msg = "success";

? ?public static final String TOURIST = "游客";

? ?private int code = SUCCESS;

? ?private T data;

? ?public ResultBean(T data) {

? ? ? ?super();

? ? ? ?this.data = data;

? ?}

? ?public ResultBean(Throwable e) {

? ? ? ?super();

? ? ? ?this.msg = e.toString();

? ? ? ?this.code = FAIL;

? ?}

? ?public ResultBean setMsg(String msg) {

? ? ? ?this.msg = msg;

? ? ? ?return this;

? ?}

? ?public ResultBean setCode(int code) {

? ? ? ?this.code = code;

? ? ? ?return this;

? ?}

? ?public ResultBean setData(T data) {

? ? ? ?this.data = data;

? ? ? ?return this;

? ?}

}

上述兩個Bean桶错,基本所有的接口返回都可以使用院刁,接口返回的統(tǒng)一化,也使得控制層的代碼更加簡潔

核心:接口返回bean的統(tǒng)一使AOP可以很好的管理任岸,寫好切入點享潜,對于后續(xù)需要做的日志管理嗅蔬,以及方法運行時間,和全局異常處理猬腰,不能再好了

下面看下剛剛的控制層所修改后的效果

? ?@GetMapping("query")

? ?public PageResultBean<List<Area>> areaList(@RequestParam(name = "pagenum",required = false,defaultValue = "1") Integer pageNum,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @RequestParam(name = "pagesize",required = false,defaultValue = "10") Integer pageSize){

? ? ? ?return new PageResultBean<List<Area>>(new PageInfo(areaService.selectAreaAll(pageNum,pageSize)));

? ?}

還可以優(yōu)化的就是兩個參數(shù)的接受姑荷,以及后續(xù)可能會有的參數(shù)查詢锣枝,可以使用PageResultBean和需要查詢參數(shù)的實體類接收

下面啟動DemoApplication

訪問:http://localhost:8080/area/query?pagenum=1&pagesize=10

返回的JSON數(shù)據(jù)撇叁,包括了總頁數(shù)陨闹,總條數(shù),當前頁數(shù)寨闹,每頁條數(shù)等繁堡,表數(shù)據(jù)在data里椭蹄,非常的實用

下面是data里的表數(shù)據(jù)

這里的顯示JSON插件為:

https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh

谷歌瀏覽器里的绳矩,推薦使用翼馆。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末应媚,一起剝皮案震驚了整個濱河市猜极,隨后出現(xiàn)的幾起案子魔吐,更是在濱河造成了極大的恐慌莱找,老刑警劉巖奥溺,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浮定,死亡現(xiàn)場離奇詭異桦卒,居然都是意外死亡方灾,警方通過查閱死者的電腦和手機碌更,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門痛单,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嘿棘,“玉大人,你說我怎么就攤上這事旭绒∧衩睿” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵挥吵,是天一觀的道長重父。 經(jīng)常有香客問我,道長蔫劣,這世上最難降的妖魔是什么坪郭? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任脉幢,我火速辦了婚禮,結(jié)果婚禮上嗦锐,老公的妹妹穿的比我還像新娘嫌松。我一直安慰自己,他們只是感情好奕污,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布萎羔。 她就那樣靜靜地躺著,像睡著了一般碳默。 火紅的嫁衣襯著肌膚如雪贾陷。 梳的紋絲不亂的頭發(fā)上缘眶,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音髓废,去河邊找鬼巷懈。 笑死,一個胖子當著我的面吹牛慌洪,可吹牛的內(nèi)容都是我干的顶燕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼冈爹,長吁一口氣:“原來是場噩夢啊……” “哼涌攻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起频伤,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤恳谎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后剂买,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惠爽,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年瞬哼,在試婚紗的時候發(fā)現(xiàn)自己被綠了婚肆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡坐慰,死狀恐怖较性,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情结胀,我是刑警寧澤赞咙,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站糟港,受9級特大地震影響攀操,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秸抚,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一速和、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剥汤,春花似錦颠放、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春欲低,著一層夾襖步出監(jiān)牢的瞬間辕宏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工砾莱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留匾效,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓恤磷,卻偏偏與公主長得像面哼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扫步,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理魔策,服務(wù)發(fā)現(xiàn),斷路器河胎,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法闯袒,類相關(guān)的語法,內(nèi)部類的語法游岳,繼承相關(guān)的語法政敢,異常的語法,線程的語...
    子非魚_t_閱讀 31,622評論 18 399
  • Mybatis 是一個持久層ORM框架胚迫,負責Java與數(shù)據(jù)庫數(shù)據(jù)交互喷户,也可以簡易理解為中介,相對于它访锻,還有個中介是...
    架構(gòu)師springboot閱讀 579評論 0 2
  • 從實習到現(xiàn)在上班已經(jīng)差不多兩年了褪尝,但是這是我第一次寫我這兩年的經(jīng)歷。說句真心話這兩年過得并不太平期犬。 在大學畢業(yè)之前...
    overall閱讀 267評論 0 0
  • 我改變不了世界河哑,可是世界也別想改變我! 說這是一部先聲奪人的片子龟虎,一點都不過分璃谨,因為《Por Una Cabeza...
    月色觸角閱讀 813評論 0 1