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


    //本文作者:cuifuan

    //本文将收录到菜单栏:《Spring全家桶》专栏中

     首发地址:https://www.javazhiyin.com/20913.html

    萌新:小哥,我在实体类写了那么多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插件

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

    安装完重启IDEA

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

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

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

    刷新Gradle之后就可以了

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

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

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

    Spring全家桶系列--SpringBoot渐入佳境
    到这里已经可以了

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

    3.API接口返回统一化

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

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

    萌新:那小哥,我又不是负责人,怎么统一呢
    小哥:最少你自己用了之后返回的API的格式是固定的,前台很好拿数据
    萌新:好的,好的开发规范,人人有责
    小哥:和你说下阿里Java开发规范文档可以看下。

    文档地址:点击查看

    萌新:收到!

    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里,非常的实用

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

    下面是data里的表数据
    Spring全家桶系列--SpringBoot渐入佳境

    这里的显示JSON插件为:

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

    谷歌浏览器里的,推荐使用。代码的github地址:

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

    Spring全家桶系列:

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

    Spring全家桶系列–SpringBoot与Mybatis结合

  • 相关阅读:
    告别08
    WinForm程序如何将子窗体嵌入到父窗体的Panel里
    几种排序算法
    接口的特征
    什么是重写
    C#异常处理
    什么是重载
    结构和类的区别
    Javascript的函数
    在ASP.NET中防止注入攻击
  • 原文地址:https://www.cnblogs.com/javazhiyin/p/9982639.html
Copyright © 2020-2023  润新知