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

1.Lombok插件

对于开发人员来说,我要解释这个什么意思,你肯定也是一知半解,直接来代码解释吧

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;

}

以上两者的效果是相同的,现在我们知道它是干嘛的了,下面开始使用吧

1.2 安装Lombok

在Intellij IDEA中安装lombok插件

安装完重启IDEA

打开设置找到上述并勾选,然后在build.gradle文件中增加

//让gradle具有内置的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();

       //这里可以有get方法证明就ok 可以使用了

       area.getType();

   }

}

2.PageHelper分页插件

萌新:小哥,我很苦恼分页这个功能怎么办?

小哥:那不是可以写好一个逻辑直接复制吗?

萌新:那也需要很多行代码,导致了需要在mapper以及业务层做很多无用功

小哥:哈哈,那我来告诉你一款分页插件,解决你的困扰

首先,在build.gradle中引入依赖

/** 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'

}

这里同时也将SpringBoot升到了2.0,具体的新功能研究后会总结一下的

pagehelper这个插件估计和Spring1.5.x的版本有兼容性问题

上面的配置都是我测试好的,直接替换然后重新刷新Gradle

上篇的自动生成的mapper.xml文件中无查询全部的方法,这里补上一下

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

   /**

    * 查询全部

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

}

上述接口的实现类加上 AreaServiceImpl.java

   /**

    *  分页核心代码

    * @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;

   }

控制层调用 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的参数

    * -required 为是否为必须传输的参数

    * -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是一款可以用测试你接口的软件,推荐花个半个小时来熟悉下

到这里已经可以了

如果你的有问题,在我github有代码,或者百度下错误,因为每个人电脑的java版本不同,环境不同

3.API接口返回统一化

现在的很多项目都是前后端分离的项目,所以后台人员返回的参数参差不齐,每次对接都需要去交流一下,造成开发效率很低。

例如,一个操作更新成功,后台甲可能就返回给前台一个1,而乙返回一个Map格式,假如批量更新呢,返回的有时候不止是1了,所以接口返回统一化很重要。

萌新:那小哥,我又不是负责人,怎么统一呢

小哥:最少你自己用了之后返回的API的格式是固定的,前台很好拿数据

萌新:好的,好的开发规范,人人有责

小哥:和你说下阿里Java开发规范文档可以看下。

文档地址: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统一返回的bean

* @return

* @time 2018-10-15 下午 9:29 根据晓风轻的ResultBean修改来的

**/

@Getter

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

   // 总记录数

   private long totalRecord;

   //总页数

   private int pageCount;

   //当前页码

   private int pageNo;

   //当前页的记录数量

   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,基本所有的接口返回都可以使用,接口返回的统一化,也使得控制层的代码更加简洁

核心:接口返回bean的统一使AOP可以很好的管理,写好切入点,对于后续需要做的日志管理,以及方法运行时间,和全局异常处理,不能再好了

下面看下刚刚的控制层所修改后的效果

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

   }

还可以优化的就是两个参数的接受,以及后续可能会有的参数查询,可以使用PageResultBean和需要查询参数的实体类接收

下面启动DemoApplication

访问:http://localhost:8080/area/query?pagenum=1&pagesize=10

返回的JSON数据,包括了总页数,总条数,当前页数,每页条数等,表数据在data里,非常的实用

下面是data里的表数据

这里的显示JSON插件为:

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

谷歌浏览器里的,推荐使用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,612评论 18 399
  • Mybatis 是一个持久层ORM框架,负责Java与数据库数据交互,也可以简易理解为中介,相对于它,还有个中介是...
    架构师springboot阅读 578评论 0 2
  • 从实习到现在上班已经差不多两年了,但是这是我第一次写我这两年的经历。说句真心话这两年过得并不太平。 在大学毕业之前...
    overall阅读 267评论 0 0
  • 我改变不了世界,可是世界也别想改变我! 说这是一部先声夺人的片子,一点都不过分,因为《Por Una Cabeza...
    月色触角阅读 813评论 0 1