SpringBoot2.x【二】快速開發(fā)插件與API規(guī)范

SpringBoot2.x快速開發(fā)插件與API規(guī)范(二)

<a name="yoxjL"></a>

準備工作

  • IDE: IntelliJ IDEA 2020.3
  • Java環(huán)境 jdk1.8
    <a name="27GWe"></a>

知識點

  • lombok
  • PageHelper
  • API接口返回統(tǒng)一化

<br />
<br />萌新:小哥,我在實體類寫了那么多get/set方法,看著很迷茫

小哥:那不是可以自動生成嗎?
萌新:雖然可以自動生成,但是如果我要修改某個變量的數(shù)據類型,我豈不是還要去修改get/set方法?
小哥:哈哈,那我今天給你說一個插件,lombok可以解決你的問題

<a name="3b339a3a"></a>

1.Lombok插件

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

<a name="7bd94405"></a>

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;
    }
}

<br />使用了Lombok之后<br />

package com.example.entity;

import lombok.Data;

@Data
public class Area {
    private Integer id;

    private Integer postalcode;

    private String address;

    private Integer type;

}

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

<a name="1516c16e"></a>

1.2 安裝Lombok

<br />在Intellij IDEA中安裝lombok插件<br />
<br />[圖片上傳失敗...(image-708973-1589197309415)]<br />
<br />安裝完重啟IDEA<br />
<br />[圖片上傳失敗...(image-8d0efa-1589197309416)]<br />
<br />打開設置找到上述并勾選,然后在build.gradle文件中增加<br />

//讓gradle具有內置的compileOnly范圍,可用于告訴gradle僅在編譯期間添加lombok
compileOnly 'org.projectlombok:lombok:1.18.4'

<br />刷新Gradle之后就可以了<br />
<br />[圖片上傳失敗...(image-82849e-1589197309416)]<br />
<br />然后隨意找個測試類,例如如下<br />

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();
        //這里可以有get方法證明就ok 可以使用了
        area.getType();
    }

}

<a name="T7IhN"></a>

2.PageHelper分頁插件

萌新:小哥,我很苦惱分頁這個功能怎么辦?
小哥:那不是可以寫好一個邏輯直接復制嗎?
萌新:那也需要很多行代碼,導致了需要在mapper以及業(yè)務層做很多無用功
小哥:哈哈,那我來告訴你一款分頁插件,解決你的困擾

<br />首先,在build.gradle中引入依賴<br />

/** buildscript中的聲明是gradle腳本自身需要使用的資源。
 *  可以聲明的資源包括依賴項、第三方插件、maven倉庫地址等
 */
buildscript {
    ext {
        springBootVersion = '2.0.1.RELEASE'
        mysqlVersion = '5.1.39'
    }
    repositories {
        //使用國內源下載依賴
        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具有內置的compileOnly范圍,可用于告訴gradle僅在編譯期間添加lombok
    compileOnly 'org.projectlombok:lombok:1.18.4'
    //分頁插件
    compile 'com.github.pagehelper:pagehelper-spring-boot-starter:1.2.10'
}

<br />這里同時也將SpringBoot升到了2.0,具體的新功能研究后會總結一下的<br />pagehelper這個插件估計和Spring1.5.x的版本有兼容性問題<br />上面的配置都是我測試好的,直接替換然后重新刷新Gradle<br />上篇的自動生成的mapper.xml文件中無查詢全部的方法,這里補上一下<br />

<select id="selectAreaAll" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from area
    </select>

<br />然后在dao借口插入方法接口 AreaMapper.java<br />

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);

    /**
     * 查詢全部
     * @return
     */
    List<Area> selectAreaAll();
}

<br />AreaService.java<br />

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);

}

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

/**
     *  分頁核心代碼
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public List<Area> selectAreaAll(Integer pageNum,Integer pageSize) {
        //這個要在你的查詢之前加哦
        PageHelper.startPage(pageNum,pageSize);
        //這里直接查詢全部就行了,分頁插件會替你做分頁,也無需擔心性能問題,會自動補上limit的
        List<Area> areaList=areaMapper.selectAreaAll();
        return areaList;
    }

<br />控制層調用 AreaController.java<br />

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

<br />然后在IDEA中啟動DemoApplication啟動類<br />用postman進行測試<br />

postman下載地址:https://www.cnblogs.com/wangfeng520/p/5892125.html
postman是一款可以用測試你接口的軟件,推薦花個半個小時來熟悉下

<br />[圖片上傳失敗...(image-9bb3a-1589197309416)]<br />到這里已經可以了<br />

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

<a name="iwQ1j"></a>

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

<br />現(xiàn)在的很多項目都是前后端分離的項目,所以后臺人員返回的參數(shù)參差不齊,每次對接都需要去交流一下,造成開發(fā)效率很低,例如,一個操作更新成功,后臺甲可能就返回給前臺一個1,而乙返回一個Map格式,假如批量更新呢,返回的有時候不止是1了,所以接口返回統(tǒng)一化很重要。<br />

萌新:那小哥,我又不是負責人,怎么統(tǒng)一呢
小哥:最少你自己用了之后返回的API的格式是固定的,前臺很好拿數(shù)據
萌新:好的,好的開發(fā)規(guī)范,人人有責
小哥:和你說下阿里Java開發(fā)規(guī)范文檔可以看下,文檔地址:https://files.cnblogs.com/files/han-1034683568/阿里巴巴Java開發(fā)手冊終極版v1.3.0.pdf
萌新:收到!

<br />PageResultBean.java<br />

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 根據曉風輕的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;
    }

}

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

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 = 0;

    public static final int FAIL = 1;

    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;
    }
}

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

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

<br />下面看下剛剛的控制層所修改后的效果<br />

@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ù)據,包括了總頁數(shù),總條數(shù),當前頁數(shù),每頁條數(shù)等,表數(shù)據在data里,非常的實用

<br />[圖片上傳失敗...(image-2c2b6d-1589197309416)]<br />
<br />下面是data里的表數(shù)據<br />[圖片上傳失敗...(image-c0651d-1589197309416)]<br />

這里的顯示JSON插件為:https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh

<a name="A2ZXs"></a>

持續(xù)更新地址

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容