做Java开发,你需要了解这些(上)

简介: 在开发中,我们写的代码肯定是越少越好,代码层次越清晰越好。那么下面就介绍一些可以减少代码量、可以让结构更清晰的好东西。本文涉及vo、dto的使用、全局异常处理、表单验证以及一些小工具的使用。

一、lombok的使用:


lombok是一个可以减少代码量的小工具,使用非常简单,只需要添加如下依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>


如果开发工具为idea,那么再安装一下lombok插件即可。安装方法:


setting ---> plugins ---> browse repositories,然后搜索lombok。


image.png


如果开发工具是eclipse,安装lombok插件就麻烦一些,百度上有很多教程,此处就不再搬运了。


添加了依赖,安装好了插件,就可以使用了。下面主要介绍它的两个注解。


1、@Data:


我们在写实体类时,每个实体类都要写set、get方法以及toString方法等,虽然编辑器可以自动生成,但还是有些麻烦,而且大量的set、get方法使代码看起来不清爽。那么可以使用@Data来搞定。在实体类上加上此注解,就相当于写了set、get、toString、equals等方法。

@Entity
@Data
public class OrderDetail {
    @Id
    private String detailId;
    private String orderId;
    private String productId;
    private String productName;
    private BigDecimal productPrice;
    private Integer productQuantity;
    private String productIcon;
}


这样的代码看起来就干净清爽多了。


2、@Slf4j:


这也是一个常用的注解。一般我们需要用日志都会像下面这样写:


Logger log = (Logger) LoggerFactory.getLogger(当前类.class);
log.error("【查询商品】商品不存在,productId={}",productId);


而加了这个注解,就不用自己创建log对象了,要用时直接用log调用对应方法就行了。


log.error("【查询商品】商品不存在,productId={}",productId);


关于lombok还有好多注解,暂且先介绍这两个常用的。


二、createTime和updateTime问题:


一般的表中,我们都会加上createTime和updateTime两个字段。然后有记录存入数据库时,要实体.setCreateTime(new Date())来赋值,更新时就要实体.setUpdateTime(new Date())。每次有新增记录或有更新时都要这样set一下,有些麻烦。其实这两个时间字段可以交给数据库管理。建表时createTime和updateTime字段这样写:

create table 'product_category'(
   ......
   `create_time` timestamp not null default current_timestamp comment '创建时间',
   `update_time` timestamp not null default current_timestamp 
                 on update current_timestamp comment '修改时间',
   ......
)


然后在对应的实体类上加@DynamicUpdate注解即可实现这两个字段的自动更新。创建时不用setCreateTime,更新时也不用setUpdateTime了。

@Entity
@DynamicUpdate // 动态更新
@Data
public class ProductCategory {
    ......
    private Date createTime;
    private Date updateTime;
}


三、枚举类的使用:


关于枚举类,我之前只是在学Java基础的时候了解过,后来老师教的一些demo中都没用到过,最近看的一个项目用到了,在此记录其用法。先看下面的代码:

@Entity
@Data
public class ProductInfo {
    ......
    private Integer productStatus;//商品状态(0正常,1下架)
}


有一个商品类,productStatus是其状态,0是上架,1是下架。如果现在要查询所有上架商品,那么做法如下:

List<ProductInfo> productInfoList = 
       productInfoRepository.findByProductStatus(0);


这里可能看得还挺清楚,0表示上架,查询上架的,那么就是productStatus = 0 的,所以传入0即可。但是在项目中,实体类一多,用0和1表示的东西一多,就很容易搞错,到时候自己都要看半天才知道0代表什么1代表什么。这种情况就可以用枚举类来处理。新建一个ProductStatusEnum枚举类:

@Getter
public enum ProductStatusEnum {
    UP(0,"上架"),
    DOWN(1,"下架")
    ;
    private Integer code;
    private String message;
    ProductStatusEnum(Integer code,String message) {
        this.code = code;
        this.message = message;
    }
}


那么查询方法就可以这样写了:

List<ProductInfo> productInfoList = 
       productInfoRepository.findByProductStatus(ProductStatusEnum.UP.getCode());


ProductStatusEnum.UP.getCode()就是0,这样一看就知道是查上架的商品。


四、VO的使用:


VO是view object的简称,中文意思是视图对象,也就是我们在controller中返回给前端的内容。一般开发时,我们要按照前端给的文档给前端返回相应的内容,比如现有api如下:


路由:GET /sell/buyer/product/list


参数:无


返回:

{
    "code": 0,
    "msg": "成功",
    "data": [
        {
            "name": "类目名1",
            "type": 1,
            "foods": [
                {
                    "id": "123456",
                    "name": "商品名1",
                    "price": 4.5,
                    "description": "xxxxx",
                    "icon": "http://xxx.com",
                }
            ]
        },
        {
            "name": "类目名2",
            "type": 2,
            "foods": [
                {
                    "id": "123457",
                    "name": "商品名2",
                    "price": 10.9,
                    "description": "xxxxx",
                    "icon": "http://xxx.com",
                },
                {
                    "id": "123457",
                    "name": "商品名3",
                    "price": 10.9,
                    "description": "xxxxx",
                    "icon": "http://xxx.com",
                }
            ]
        }
    ]
}


咋一看很复杂,其实不然。一个中括号就表示里面的是list。那么可以知道,最外层是由code、msg和类目的list组成;第二层就是由类目名name、type和商品的list组成;商品的list就包含了商品的信息。那么要如何构造这样的返回对象呢?先从最外层开始写。根据最外层的三个字段,可以写出ResultVo类:

/**
 * 返回给前端的最外层对象
 * Create by zhu on 2018/10/7
 */
@Data
public class ResultVo<T> {
    private Integer code;//错误码
    private String msg;//提示信息
    private T data;//返回的内容
}


这里data定义为泛型,这样就可以通用。


现在将ResultVo对象返回给前端:

@GetMapping("/test")
 public ResultVo test(){
        ResultVo resultVo = new ResultVo();
        resultVo.setCode(0);
        resultVo.setMsg("test");
        resultVo.setData("这是内容");
        return resultVo;
 }


就会得到如下效果:


image.png


说明最外层是没有错的,根据api提供的信息又可以写出如下vo:

@Data
public class ProductVo {
    //这里写的字段名与前端api需要的不一致没关系,加上如下注解,直接里面写api需要的字段名
    @JsonProperty("name")
    private String categoryName;
    @JsonProperty("type")
    private Integer categoryType;
    @JsonProperty("foods")//这个foods是一个商品的list
    private List<ProductInfoVo> productInfoVoList;
}

//这个就是最里层的商品对象
@Data
public class ProductInfoVo {
    @JsonProperty("id")
    private String productId;
    @JsonProperty("name")
    private String productName;
    @JsonProperty("price")
    private BigDecimal productPrice;
    @JsonProperty("description")
    private String productDescription;
    @JsonProperty("icon")
    private String productIcon;
}


注意,前端需要的name其实是类目名,如果这个vo也直接定义变量name,到时候会搞不清楚到底是商品的name还是类目的name。解决方案是:这里应该是什么就写什么,然后通过@JsonProperty("xxx")来指定返回给前端时的名字。


写好后再去controller中:

@GetMapping("/test")
    public ResultVo test() {
        ResultVo resultVo = new ResultVo();
        ProductVo productVo = new ProductVo();
        ProductInfoVo productInfoVo = new ProductInfoVo();
        productInfoVo.setProductName("商品1");
        productVo.setProductInfoVoList(Arrays.asList(productInfoVo));
        productVo.setCategoryName("类目1");
        resultVo.setData(Arrays.asList(productVo));
        resultVo.setMsg("成功");
        resultVo.setCode(0);
        return resultVo;
    }


把最里层的赋好值设置给中间层,中间层赋好值设置给最外层,再把最外层返回给前端,效果如下:


image.png




这样返回的格式就对了,和api一致。接下来要做的事就是从数据库查出相应的记录,然后赋给这三个对象就行了。


从上面的controller中可以发现,我们每次都要new一个最外层的ResultVo对象,然后setCode、setMsg、setData。每个方法中都new一个还是很麻烦的,所以可以封装一下:

public class ResultVoUtil {
    /** 成功时使用 */
    public static ResultVo success(Object object){
        ResultVo resultVo = new ResultVo();
        resultVo.setData(object);
        resultVo.setCode(0);
        resultVo.setMsg("成功");
        return resultVo;
    }
    /** 成功时且不需要返回值时使用 */
    public static ResultVo success(){
        return success(null);
    }
    /** 请求错误时使用 */
    public static ResultVo error(Integer code,String msg){
        ResultVo resultVo = new ResultVo();
        resultVo.setCode(code);
        resultVo.setMsg(msg);
        return resultVo;
    }
}


那么上面的controller就可以改成:

@GetMapping("/test")
    public ResultVo test() {
        ProductVo productVo = new ProductVo();
        ProductInfoVo productInfoVo = new ProductInfoVo();
        productInfoVo.setProductName("商品1");
        productVo.setProductInfoVoList(Arrays.asList(productInfoVo));
        productVo.setCategoryName("类目1");
        return ResultVoUtil.success(Arrays.asList(productVo));
    }


这样代码看起来就简洁多了,而且这个ResultVoUtil也是通用的,传入相应的Object对象即可。




相关文章
|
1月前
|
Java API Maven
如何使用Java开发抖音API接口?
在数字化时代,社交媒体平台如抖音成为生活的重要部分。本文详细介绍了如何用Java开发抖音API接口,从创建开发者账号、申请API权限、准备开发环境,到编写代码、测试运行及注意事项,全面覆盖了整个开发流程。
130 10
|
1月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
|
21小时前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
23天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
45 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
11天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
66 13
|
16天前
|
算法 Java API
如何使用Java开发获得淘宝商品描述API接口?
本文详细介绍如何使用Java开发调用淘宝商品描述API接口,涵盖从注册淘宝开放平台账号、阅读平台规则、创建应用并申请接口权限,到安装开发工具、配置开发环境、获取访问令牌,以及具体的Java代码实现和注意事项。通过遵循这些步骤,开发者可以高效地获取商品详情、描述及图片等信息,为项目和业务增添价值。
49 10
|
9天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
48 2
|
19天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
46 2
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。