zoukankan      html  css  js  c++  java
  • 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结合

  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/javazhiyin/p/9982639.html
Copyright © 2011-2022 走看看