做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
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
62 4
|
30天前
|
监控 Java 测试技术
Java开发现在比较缺少什么工具?
【10月更文挑战第15天】Java开发现在比较缺少什么工具?
34 1
|
1月前
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
56 2
|
11天前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
24 4
|
12天前
|
缓存 监控 Java
如何运用JAVA开发API接口?
本文详细介绍了如何使用Java开发API接口,涵盖创建、实现、测试和部署接口的关键步骤。同时,讨论了接口的安全性设计和设计原则,帮助开发者构建高效、安全、易于维护的API接口。
35 4
|
23天前
|
开发框架 JavaScript 前端开发
HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
75 8
|
18天前
|
SQL Java 程序员
倍增 Java 程序员的开发效率
应用计算困境:Java 作为主流开发语言,在数据处理方面存在复杂度高的问题,而 SQL 虽然简洁但受限于数据库架构。SPL(Structured Process Language)是一种纯 Java 开发的数据处理语言,结合了 Java 的架构灵活性和 SQL 的简洁性。SPL 提供简洁的语法、完善的计算能力、高效的 IDE、大数据支持、与 Java 应用无缝集成以及开放性和热切换特性,能够大幅提升开发效率和性能。
|
18天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
36 2
|
18天前
|
监控 Java 数据库连接
在Java开发中,数据库连接管理是关键问题之一
在Java开发中,数据库连接管理是关键问题之一。本文介绍了连接池技术如何通过预创建和管理数据库连接,提高数据库操作的性能和稳定性,减少资源消耗,并简化连接管理。通过示例代码展示了HikariCP连接池的实际应用。
18 1
|
27天前
|
Java 大数据 API
别死脑筋,赶紧学起来!Java之Steam() API 常用方法使用,让开发简单起来!
分享Java Stream API的常用方法,让开发更简单。涵盖filter、map、sorted等操作,提高代码效率与可读性。关注公众号,了解更多技术内容。