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

简介: 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插件


image.png


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


  1. //让gradle具有内置的compileOnly范围,可用于告诉gradle仅在编译期间添加lombok
  2. compileOnly 'org.projectlombok:lombok:1.18.4'


刷新Gradle之后就可以了


image.png


然后随意找个测试类,例如如下


  1. package com.example.demo;

  2. import com.example.entity.Area;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import org.springframework.test.context.junit4.SpringRunner;

  7. @RunWith(SpringRunner.class)
  8. @SpringBootTest
  9. publicclassDemoApplicationTests{

  10.    @Test
  11.    publicvoid contextLoads(){
  12.        Area area=newArea();
  13.        //这里可以有get方法证明就ok 可以使用了
  14.        area.getType();
  15.    }

  16. }


2.PageHelper分页插件


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

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

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

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

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

  1. /** buildscript中的声明是gradle脚本自身需要使用的资源。
  2. *  可以声明的资源包括依赖项、第三方插件、maven仓库地址等
  3. */
  4. buildscript {
  5.    ext {
  6.        springBootVersion ='2.0.1.RELEASE'
  7.        mysqlVersion ='5.1.39'
  8.    }
  9.    repositories {
  10.        //使用国内源下载依赖
  11.        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
  12.    }
  13.    dependencies {
  14.        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  15.    }
  16. }
  17. // 应用Java插件
  18. apply plugin:'java'
  19. //让工程支持IDEA的导入
  20. apply plugin:'idea'
  21. apply plugin:'org.springframework.boot'

  22. group='com.example'
  23. version ='0.0.1-SNAPSHOT'
  24. sourceCompatibility =1.8
  25. //build.gradle文件中直接声明的依赖项、仓库地址等信息是项目自身需要的资源。
  26. repositories {
  27.    maven { url 'http://maven.aliyun.com/nexus/content/groups/public/'}
  28.    mavenCentral()
  29. }

  30. /**
  31. * 在gradle里,对依赖的定义有6种
  32. * compile, runtime, testCompile, testRuntime, providedCompile,providedRuntime
  33. * compile:需要引用这个库才能进行编译工作
  34. * testRuntime : 测试依赖范围
  35. * 其他的了解:http://shmilyaw-hotmail-com.iteye.com/blog/2345439
  36. */
  37. dependencies {
  38.    compile('org.springframework.boot:spring-boot-starter-web:2.0.1.RELEASE')
  39.    compile('com.alibaba:druid:1.0.29')
  40.    testCompile('org.springframework.boot:spring-boot-starter-test:2.0.1.RELEASE')
  41.    //这里的版本可以在上述定义
  42.    compile 'mysql:mysql-connector-java:5.1.39'
  43.    compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
  44.    //让gradle具有内置的compileOnly范围,可用于告诉gradle仅在编译期间添加lombok
  45.    compileOnly 'org.projectlombok:lombok:1.18.4'
  46.    //分页插件
  47.    compile 'com.github.pagehelper:pagehelper-spring-boot-starter:1.2.10'
  48. }


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


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


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


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


  1.    <selectid="selectAreaAll"resultMap="BaseResultMap">
  2.        select
  3.        <includerefid="Base_Column_List"/>
  4.        from area
  5.    </select>


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



  1. package com.example.dao;

  2. import com.example.entity.Area;

  3. import java.util.List;

  4. publicinterfaceAreaMapper{
  5.    int deleteByPrimaryKey(Integer id);

  6.    int insert(Area record);

  7.    int insertSelective(Area record);

  8.    Area selectByPrimaryKey(Integer id);

  9.    int updateByPrimaryKeySelective(Area record);

  10.    int updateByPrimaryKey(Area record);

  11.    /**
  12.     * 查询全部
  13.     * @return
  14.     */
  15.    List<Area> selectAreaAll();
  16. }


AreaService.java


  1. package com.example.service;

  2. import com.example.entity.Area;

  3. import java.util.List;

  4. /**
  5. * 这里给dao层的代码拷贝过来先使用
  6. * created by cfa  2018-11-08 下午 9:56
  7. **/
  8. publicinterfaceAreaService{


  9.    int deleteByPrimaryKey(Integer id);

  10.    int insert(Area record);

  11.    int insertSelective(Area record);

  12.    Area selectByPrimaryKey(Integer id);

  13.    int updateByPrimaryKeySelective(Area record);

  14.    int updateByPrimaryKey(Area record);

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

  16. }


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


  1.    /**
  2.     *  分页核心代码
  3.     * @param pageNum
  4.     * @param pageSize
  5.     * @return
  6.     */
  7.    @Override
  8.    publicList<Area> selectAreaAll(Integer pageNum,Integer pageSize){
  9.        //这个要在你的查询之前加哦
  10.        PageHelper.startPage(pageNum,pageSize);
  11.        //这里直接查询全部就行了,分页插件会替你做分页,也无需担心性能问题,会自动补上limit的
  12.        List<Area> areaList=areaMapper.selectAreaAll();
  13.        return areaList;
  14.    }


控制层调用 AreaController.java


  1. package com.example.controller;


  2. import com.example.entity.Area;
  3. import com.example.service.AreaService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. import org.springframework.web.bind.annotation.RestController;

  8. import java.util.List;

  9. @RestController
  10. @RequestMapping("area")
  11. publicclassAreaController{

  12.    privatefinalAreaService areaService;

  13.    @Autowired
  14.    publicAreaController(AreaService areaService){
  15.        this.areaService = areaService;
  16.    }

  17.    /**
  18.     * 这里的@RequestParam(name = "pagesize",required = false,defaultValue = "10")
  19.     * -name 为传输时为接受key为pagesize的参数
  20.     * -required 为是否为必须传输的参数
  21.     * -default 就是如果没有接收到值 就给予默认值
  22.     * @param pageNum
  23.     * @param pageSize
  24.     * @return
  25.     */
  26.    @RequestMapping("query")
  27.    publicList<Area> areaList(@RequestParam(name ="pagenum",required =false,defaultValue ="1")Integer pageNum,
  28.                               @RequestParam(name ="pagesize",required =false,defaultValue ="10")Integer pageSize){
  29.        return areaService.selectAreaAll(pageNum,pageSize);
  30.    }
  31. }


然后在IDEA中启动DemoApplication启动类



用postman进行测试


postman下载地址:

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

postman是一款可以用测试你接口的软件,推荐花个半个小时来熟悉下


image.png


到这里已经可以了


如果你的有问题,在我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

  1. package com.example.beans;

  2. import com.github.pagehelper.PageInfo;
  3. import lombok.Getter;

  4. import java.io.Serializable;

  5. /*
  6. * description : 分页API统一返回的bean
  7. * @return
  8. * @time 2018-10-15 下午 9:29 根据晓风轻的ResultBean修改来的
  9. **/
  10. @Getter
  11. publicclassPageResultBean<T>extendsResultBean<T>implementsSerializable{

  12.    // 总记录数
  13.    privatelong totalRecord;

  14.    //总页数
  15.    privateint pageCount;

  16.    //当前页码
  17.    privateint pageNo;

  18.    //当前页的记录数量
  19.    privateint pageSize;

  20.    publicPageResultBean(PageInfo<T> pageInfo){
  21.        super.setData((T) pageInfo.getList());
  22.        this.setPageNo(pageInfo.getPageNum())
  23.                .setPageSize(pageInfo.getPageSize())
  24.                .setPageCount(pageInfo.getPages())
  25.                .setTotalRecord(pageInfo.getTotal());
  26.    }

  27.    publicPageResultBean setTotalRecord(long totalRecord){
  28.        this.totalRecord = totalRecord;
  29.        returnthis;
  30.    }

  31.    publicPageResultBean setPageCount(int pageCount){
  32.        this.pageCount = pageCount;
  33.        returnthis;
  34.    }

  35.    publicPageResultBean setPageNo(int pageNo){
  36.        this.pageNo = pageNo;
  37.        returnthis;
  38.    }

  39.    publicPageResultBean setPageSize(int pageSize){
  40.        this.pageSize = pageSize;
  41.        returnthis;
  42.    }

  43.    @Override
  44.    publicString toString(){
  45.        return"PageResultBean{"+
  46.                "totalRecord="+ totalRecord +
  47.                ", pageCount="+ pageCount +
  48.                ", pageNo="+ pageNo +
  49.                ", pageSize="+ pageSize +
  50.                '}';
  51.    }

  52.    @Override
  53.    publicPageResultBean setMsg(String msg){
  54.        super.setMsg(msg);
  55.        returnthis;
  56.    }

  57.    @Override
  58.    publicPageResultBean setCode(int code){
  59.        super.setCode(code);
  60.        returnthis;
  61.    }

  62.    @Override
  63.    publicPageResultBean setData(T data){
  64.        super.setData(data);
  65.        returnthis;
  66.    }

  67. }


附上晓风轻所著的ResultBean(略有修改) ResultBean.java


  1. package com.example.beans;

  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;

  4. import java.io.Serializable;

  5. @Data
  6. @NoArgsConstructor
  7. publicclassResultBean<T>implementsSerializable{

  8.    privatestaticfinallong serialVersionUID =1L;

  9.    publicstaticfinalint NO_LOGIN =-1;

  10.    publicstaticfinalint SUCCESS =1;

  11.    publicstaticfinalint FAIL =0;

  12.    publicstaticfinalint NO_PERMISSION =2;

  13.    publicstaticfinalint USERNAME_EXIST =-909;

  14.    privateString msg ="success";

  15.    publicstaticfinalString TOURIST ="游客";

  16.    privateint code = SUCCESS;

  17.    private T data;

  18.    publicResultBean(T data){
  19.        super();
  20.        this.data = data;
  21.    }

  22.    publicResultBean(Throwable e){
  23.        super();
  24.        this.msg = e.toString();
  25.        this.code = FAIL;
  26.    }

  27.    publicResultBean setMsg(String msg){
  28.        this.msg = msg;
  29.        returnthis;
  30.    }

  31.    publicResultBean setCode(int code){
  32.        this.code = code;
  33.        returnthis;
  34.    }

  35.    publicResultBean setData(T data){
  36.        this.data = data;
  37.        returnthis;
  38.    }
  39. }


上述两个Bean,基本所有的接口返回都可以使用,接口返回的统一化,也使得控制层的代码更加简洁


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


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


  1.    @GetMapping("query")
  2.    publicPageResultBean<List<Area>> areaList(@RequestParam(name ="pagenum",required =false,defaultValue ="1")Integer pageNum,
  3.                                   @RequestParam(name ="pagesize",required =false,defaultValue ="10")Integer pageSize){
  4.        returnnewPageResultBean<List<Area>>(newPageInfo(areaService.selectAreaAll(pageNum,pageSize)));
  5.    }

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

下面启动DemoApplication


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

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



image.png


下面是data里的表数据


微信图片_20220218125807.jpg


这里的显示JSON插件为:

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

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

代码的github地址:

https://github.com/cuifuan/springboot-demo


相关文章
|
2月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
53 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
2月前
|
监控 Java 应用服务中间件
Spring和Spring Boot的区别
Spring和Spring Boot的主要区别,包括项目配置、开发模式、项目依赖、内嵌服务器和监控管理等方面,强调Spring Boot基于Spring框架,通过约定优于配置、自动配置和快速启动器等特性,简化了Spring应用的开发和部署过程。
54 19
|
2月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
68 2
|
2月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
112 1
|
2月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
28 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
2月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
28 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
2月前
|
Java 测试技术 Spring
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
这篇文章介绍了Spring Boot中配置文件的语法、如何读取配置文件以及如何通过静态工具类读取配置文件。
61 0
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
|
2月前
|
SQL Java 数据库
Springboot+spring-boot-starter-data-jdbc实现数据库的操作
本文介绍了如何使用Spring Boot的spring-boot-starter-data-jdbc依赖来操作数据库,包括添加依赖、配置数据库信息和编写基于JdbcTemplate的数据访问代码。
91 2
|
2月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
182 2
|
2月前
|
前端开发 安全 Java
【Spring】Spring Boot项目创建和目录介绍
【Spring】Spring Boot项目创建和目录介绍
84 2
下一篇
无影云桌面