排除非表字段的3种方式

常见编程场景:
实体类中某个变量不对应数据库的表中的任何字段,用于暂时保存临时数据或者通过某种方式计算或组装的数据。

文章目录

一、举个栗子:

1.1 在User实体类中,添加remark属性

//备注 保存用于程序调用或者组装的数据,在数据库中没有对应的字段
@Data
@TableName("mp_user")
public class User {

//主键
@TableId
private Long userId;
//姓名
@TableField("name")
private String roleName;
//年龄
private Integer age;
//邮箱
private String email;
//创建时间
private LocalDateTime createTime;

//备注 保存用于程序调用或者组装的数据,在数据库中没有对应的字段
private String remark;
}

1.2 执行插入操作:

 /**
* 测试与数据库无对应字段
*/
@Test
public void insertNoCorField() {

User user = new User();
user.setRoleName("gblfy");
user.setAge(26);
user.setCreateTime(LocalDateTime.now());
user.setRemark("数据库中无对应字段");
int rows = userMapper.insert(user);
System.out.println("影响数据库的条数:" + rows);
}

1.3 异常信息:

org.springframework.jdbc.BadSqlGrammarException: 
### Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column 'remark' in 'field list'
### The error may exist in com/gblfy/mp/mybatisplus/samplesquickstart/mapper/UserMapper.java (best guess)
### The error may involve com.gblfy.mp.mybatisplus.samplesquickstart.mapper.UserMapper.insert-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO mp_user ( user_id, name, age, create_time, remark ) VALUES ( ?, ?, ?, ?, ? )
### Cause: java.sql.SQLSyntaxErrorException: Unknown column 'remark' in 'field list'
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Unknown column 'remark' in 'field list'

1.4 问题定位

数据库中无remark字段列,插入数据库时,字段数量对应不上,导致抛出异常

1.5 解决方案

二、针对以上场景,MP提供了三种解决方案

2.1 第一种解决方案:

2.1.1 在remark属性上添加transient 关键字

  • 表明不参与序列化过程
/*第一种情况*/
private transient String remark;

2.1.2 再次执行插入成功:

  /**
* 第一种解决方案:
*
* 添加transient关键字,不参与序列化过程
*
* 测试与数据库无对应字段
*/
@Test
public void insertNoCorField() {

User user = new User();
user.setRoleName("gblfy");
user.setAge(26);
user.setCreateTime(LocalDateTime.now());
user.setRemark("数据库中无对应字段");
int rows = userMapper.insert(user);
System.out.println("影响数据库的条数:" + rows);
}

2.1.3 控制台输出

MyBatis-Plus_入门试炼03_字段

上面加上transient 关键字,不参与序列化过程,但是,我需要参与序列化怎么办呢?

2.2 第二种解决方案:

2.2.1 在remark属性上添加static 关键字

  • 表明时静态的,需要手动添加set和get方法,lombok不会生成
    /*第二种情况*/
//备注 保存用于程序调用或者组装的数据,在数据库中没有对应的字段
private static String remark;

public static String getRemark() {
return remark;
}
public static void setRemark(String remark) {
User.remark = remark;
}

2.2.2 再次执行插入成功:

/**
* 第二种解决方案:
*
* 1.添加static关键字
* 2.表明remark属性是静态的
* 3.可以用类名直接调用
*
* 测试与数据库无对应字段
*/
@Test
public void insertNoCorField2() {

User user = new User();
user.setRoleName("gblfy");
user.setAge(26);
user.setCreateTime(LocalDateTime.now());

//用类名直接调用setRemark方法
User.setRemark("数据库中无对应字段");
int rows = userMapper.insert(user);
System.out.println("影响数据库的条数:" + rows);
}

2.2.3 控制台输出

MyBatis-Plus_入门试炼03_解决方案_02

第二种 remark这个属性想每个对象对应一个,应该如何处理?

2.3 第三种解决方案(建议使用):

1.添加@TableField(exist = false)注解,并将exist设置为false,默认为true 数据库有此字段
2.表明remark属性在数据库是不存在的

2.3.1 在remark属性上添加@TableField注解

    /*第三种情况*/
@TableField(exist = false)
private String remark;

2.3.2 在此执行插入成功:

/**
* 第三种解决方案:
*
* 1.添加@TableField(exist = false)注解,并将exist设置为false,默认为true 数据库有此字段
* 2.表明remark属性在数据库是不存在的
*
* 测试与数据库无对应字段
*/
@Test
public void insertNoCorField3() {

User user = new User();
user.setRoleName("gblfy");
user.setAge(26);
user.setCreateTime(LocalDateTime.now());

//用类名直接调用setRemark方法
user.setRemark("第三种情况_数据库中无对应字段");
int rows = userMapper.insert(user);
System.out.println("影响数据库的条数:" + rows);
}

2.3.3 控制台输出

MyBatis-Plus_入门试炼03_解决方案_03