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

萌新:小哥,我在实体类写了那么多get/set方法,看着很迷茫

小哥:那不是可以自动生成吗?

萌新:虽然可以自动生成,但是如果我要修改某个变量的数据类型,我岂不是还要去修改get/set方法?

小哥:哈哈,那我今天给你说一个插件,lombok可以解决你的问题

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/阿里巴巴Java开发手册终极版v1.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

谷歌浏览器里的,推荐使用,这里或许需要梯子,不过谷歌插件里好像有个谷歌访问助手,自行研究吧,哈哈

代码的github地址:https://github.com/cuifuan/springboot-demo

Spring全家桶——SpringBoot渐入佳境的更多相关文章

  1. Spring全家桶——SpringBoot之AOP详解

    Spring全家桶--SpringBoot之AOP详解 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关键单元是类,而在AOP中,模块化单元是方 ...

  2. Spring全家桶–SpringBoot Rest API

    Spring Boot通过提供开箱即用的默认依赖或者转换来补充Spring REST支持.在Spring Boot中编写RESTful服务与SpringMVC没有什么不同.总而言之,基于Spring ...

  3. Spring全家桶系列–[SpringBoot入门到跑路]

    //本文作者:cuifuan Spring全家桶————[SpringBoot入门到跑路] 对于之前的Spring框架的使用,各种配置文件XML.properties一旦出错之后错误难寻,这也是为什么 ...

  4. Spring全家桶系列–SpringBoot渐入佳境

    //本文作者:cuifuan //本文将收录到菜单栏:<Spring全家桶>专栏中 首发地址:https://www.javazhiyin.com/20913.html 萌新:小哥,我在实 ...

  5. Spring全家桶系列–SpringBoot之AOP详解

    //本文作者:cuifuan //本文将收录到菜单栏:<Spring全家桶>专栏中 面向方面编程(AOP)通过提供另一种思考程序结构的方式来补充面向对象编程(OOP). OOP中模块化的关 ...

  6. Spring全家桶一一SpringBoot与Mybatis

    Spring全家桶系列一一SpringBoot与Mybatis结合 本文授权"Java知音"独家发布. Mybatis 是一个持久层ORM框架,负责Java与数据库数据交互,也可以 ...

  7. 10分钟详解Spring全家桶7大知识点

    Spring框架自2002年诞生以来一直备受开发者青睐,它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflow等解决方案.有人亲切的称之为 ...

  8. Java秋招面试复习大纲(二):Spring全家桶+MyBatis+MongDB+微服务

    前言 对于那些想面试高级 Java 岗位的同学来说,除了算法属于比较「天方夜谭」的题目外,剩下针对实际工作的题目就属于真正的本事了,热门技术的细节和难点成为了面试时主要考察的内容. 这里说「天方夜谭」 ...

  9. 一文解读Spring全家桶 (转)

    Spring框架自2002年诞生以来一直备受开发者青睐,它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflow等解决方案.有人亲切的称之为 ...

随机推荐

  1. Pytorch使用PIL的读取单张图片并显示

    1. Image.open(fp, mode="r") 调用此方法需要引入头文件:from PIL import Image. 参数说明: fp:图片路径,可为绝对路径或相对路径. ...

  2. centos6更换yum源和epel源

    epel是yum的一个软件用源,包含了很多基本源中没有的软件,cobbler就属于基本源中没有的软件,所以需要安装epel源. yum源: wget -O /etc/yum.repos.d/CentO ...

  3. Joomla CMS 3.2-3.4.4 SQL注入 漏洞分析

    RickGray · 2015/10/26 11:24 昨日,Joomla CMS发布新版本3.4.5,该版本修复了一个高危的SQL注入漏洞,3.2至3.4.4版本都受到影响.攻击者通过该漏洞可以直接 ...

  4. 华为设备RIP实施和理论详解

    1.路由协议基础 共同的目的:更新.维护和控制3层的路由 工作机制: RIP,封装在UDP这个协议上,端口号520(优先级100) OSPF,封装在IP层,协议号89(优先级,内部10,外部是150- ...

  5. opencv-11-中值滤波及自适应中值滤波

    开始之前 在上一篇我们实现了读取噪声图像, 然后 进行三种形式的均值滤波得到结果, 由于我们自己写的均值滤波未作边缘处理, 所以效果有一定的下降, 但是总体来说, 我们得到的结果能够说明我们的算法执行 ...

  6. Image Filter and Recover

    这是CS50的第四次大作业,顺便学习了图像的入门知识. 基础 黑白图(bitmap)的每个像素点只能取值0/1,1代表白色,0代表黑色. 常见的图片格式有JPEG/PNG/BMP,这些格式都支持RGB ...

  7. ACM卡常处理办法(虽然我到现在没遇到)

    今天做预流推送,一样的代码.别人500MS(OI选手)而我5S,百思不得其解,然后我知道了还有卡常这一说. 我们今天就来看一看吧: 1.循环展开: 在缓存和寄存器允许的情况下一条语句内大量的展开运算会 ...

  8. 06 __init__ 和 __new__的关系和不同

    一. 双下new 和 双下init 关系 首先从__new__(cls,a,b,c)的参数说说起,__new__方法的第一个参数是这个类,而其余的参数会在调用成功后全部传递给__init__方法初始化 ...

  9. Android原生多语言切换方案,兼容Android10

    前言 一个应用若需要国际化,至少需要支持中文和英语这两种语言,而同时随着谷歌的系统的更新,安卓系统可以设置当前语言的首选语言.因此,本文立足于此,多语言的切换方案为:App固定的文字内容,跟随系统,中 ...

  10. QT入门指导

    罗列一些QT学习资料 1. http://www.qter.org/ 包含很多教程,包括著名的<学习之路>系列. 2. http://www.qtcn.org/bbs/index-htm- ...