Spring全家桶——SpringBoot渐入佳境

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插件

image

安装完重启IDEA

image

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

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

刷新Gradle之后就可以了

image

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

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

image

到这里已经可以了

如果你的有问题,在我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里,非常的实用

image

下面是data里的表数据

image

这里的显示JSON插件为:https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh
谷歌浏览器里的,推荐使用,这里或许需要梯子,不过谷歌插件里好像有个谷歌访问助手,自行研究吧,哈哈

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

全部评论

相关推荐

避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
06-13 12:13
已编辑
东北大学 射频工程师
26毕业的,日常实习还能找到吗
求实习的青提很想去大厂:目前应该还有hc吧,腾讯感觉还有hc,最近捞了我好几次,因为目前有offer,所以不准备面了,可以再找找,不行的话就找找中小厂试试,因为我之前也找了好久,准备放弃了,结果有个岗位流程特别顺利,然后就oc,只能说坚持下试试,万一呢💪
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务