前言:在阿里开发手册中,有一条开发规范是强制规定的:POJO 类中的任何布尔类型的变量,都不要加 is 前缀。
而同样是在阿里开发手册中,在 MySQL 规约中的建表约定第一条,表达是与否的变量采用 is_xxx 的命名方式。
很多人就懵逼了,在我们生产项目中集成的mybatis或者mybatis-plus,如果pojo实体对象的属性和表字段不相同的话,
怎么能够映射呢?那为什么任何布尔类型的变量,都不能加 is 前缀呢?下面我们慢慢说下原因。
定义一个pojo类
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
@Builder
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String name;
private Integer age;
private String addr;
private Integer isModify; //是否被修改
private Boolean isDelete; //是否被删除
}
看到这个User对象有两个变量属性,一个是isModify,另一个是isDelete,虽然两个变量都是以is开头,但是对应的数据类型是不同的,isModify对应的数据类型是Integer,isDelete对应的数据类型是Boolean。
@Data:这个注解相信大家都会在生产项目中用到,这是lombok框架中的一个注解,能为我们在项目中省略大量getter和setter代码。下面是@Data的定义,可以看到它是由Getter、Setter、RequiredArgsConstructor、ToString和EqualsAndHashCode组成的。
package lombok;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @see Getter
* @see Setter
* @see RequiredArgsConstructor
* @see ToString
* @see EqualsAndHashCode
* @see lombok.Value
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
String staticConstructor() default "";
}
由@Data注解,生成User对象的isModify,isDelete的Getter和Setter方法对下所示,可以看到布尔类型的变量isDelete所对应的Getter和Setter方法会把is前缀省略掉,会导致得不到isDelete属性。因为定义为基本数据类型 Boolean isDelete 的属性,它的方法也是 isDelete(),框架在反向解析的时候,“误以为”对应的属性名称是 delete,导致属性获取不到。
public Integer getIsModify() {
return isModify;
}
public void setIsModify(Integer isModify) {
this.isModify = isModify;
}
public Boolean getDelete() {
return isDelete;
}
public void setDelete(Boolean delete) {
isDelete = delete;
}
不使用@Data注解,而使用开发工具IDEA,自动生成Getter和Setter方法,同样会存在这个问题。而要解决这个问题,需要我们手动写Getter和Setter方法,显然这种方式是很繁重的,不可取的,不仅增加代码的可读性,而且增加开发的工作量和成本。
public Integer getIsModify() {
return isModify;
}
public void setIsModify(Integer isModify) {
this.isModify = isModify;
}
public Boolean getIsDelete() {
return isDelete;
}
public void setIsDelete(Boolean isDelete) {
this.isDelete = isDelete;
}
那如果建表字段采用 is_xxx 的命名方式,那对应的实体POJO类应该怎么定义呢?怎么和持久层框架映射呢?
方法一: 表字段对应的is_xxx变量使用Integer数据类型,不使用布尔数据类型。如上面的User对象所示,Integer数据类型的isModify就不存在反向解析获取不到isModify变量的问题。
方法二:表字段对应的is_xxx变量依旧使用布尔数据类型,但是POJO类的变量就把is前缀去掉,然后在xml配置文件中在设置从 is_xxx 到 xxx 的映射关系。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserMapper">
<resultMap type="com.example.demo.entity.User" id="userMap">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="name" column="name"/>
<result property="addr" column="addr"/>
<result property="isModify" column="is_modify"/>
<result property="delete" column="is_delete"/>
</resultMap>
</mapper>