# :-: [MybatisPlus中@TableField注解的使用](https://blog.csdn.net/qq_40241957/article/details/101772536)
## 实现
官方文档说明:
* com.baomidou.mybatisplus.annotations.TableField
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190930151444851.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMjQxOTU3,size_16,color_FFFFFF,t_70)
* TableField 注解新增属性 update 预处理 set 字段自定义注入
(`讲解:比如我们使用mybatisplus自带的insert()方法向数据库插入数据时,假设我们给age字段赋值为1,但是我们在age字段上的@TableField注解里面加了update="%s+1",那么真真插入到数据库的值就是age=2,而不是age+1了`)
```
例如:@TableField(.. , update="%s+1") 其中 %s 会填充为字段
输出 SQL 为:update 表 set 字段=字段+1 where ...
```
* 如果给某个字段上@TableField注解里面写update=“now()”,那么最后我们使用mybatisplus自带的insert()方法向数据库插入数据时,这个字段插入到数据库中的值就为当前时间,看下面代码的sql语句即可明白
~~~json
例如:@TableField(.. , update="now()") 使用数据库时间
输出 SQL 为:update 表 set 字段=now() where ...
~~~
* TableField 注解新增属性 condition 预处理 WHERE 实体条件自定义运算规则,下面会有代码讲解
~~~json
@TableField(condition = SqlCondition.LIKE)
private String name;
输出 SQL 为:select 表 where name LIKE CONCAT('%',值,'%')
~~~
讲解:举个例子来说明@TableField(condition = SqlCondition.LIKE)的作用
~~~java
@Data
@TableName("admin_role")
public class RoleDO extends Model<RoleDO> {
/**
* 角色ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 角色名称
*/
@TableField(condition = SqlCondition.LIKE)
private String name;
/**
* 角色描述
*/
private String description;
/**
* 是否启用:0-不可用,1-可用
*/
private Boolean enabled;
/**
* 删除标示:0-未删除,1-已删除
*/
@TableLogic
private Boolean deleted;
/**
* 创建人ID
*/
protected Long creatorId;
/**
* 创建人
*/
protected String creator;
/**
* 创建时间
*/
@SuppressFBWarnings("EI_EXPOSE_REP")
protected Date dateCreated;
/**
* 修改人ID
*/
protected Long modifierId;
/**
* 修改人
*/
protected String modifier;
/**
* 更新时间
*/
@SuppressFBWarnings("EI_EXPOSE_REP")
protected Date lastModified;
/** 指定主键 */
@Override
protected Serializable pkVal() {
return this.id;
}
}
~~~
`我们通过直接给EntityWrapper对象传入RoleDO实体类来构造EntityWrapper`, EntityWrapper eWrapper = new EntityWrapper(roleDO); (代码如下)
~~~java
/**
* 查询角色列表(分页)
*
* @param roleParam 角色参数
* @return 查询角色分页列表
*/
public Page<RoleDO> selectListPage(ListRoleParam roleParam) {
RoleDO roleDO = new RoleDO();
BeanUtils.copyProperties(roleParam, roleDO);
Page<RoleDO> page = new Page<RoleDO>((int)roleParam.getPi(), (int)roleParam.getPs()); //得到分页的信息
EntityWrapper<RoleDO> eWrapper = new EntityWrapper<RoleDO>(roleDO);//构建条件查询对象
Page<RoleDO> roleDOList = roleDO.selectPage(page, eWrapper);//这里使用的就是Model提供的AR
return roleDOList;
}
~~~
而对于name这样的字段在日常查询中往往是通过like方式来进行匹配的而非精确匹配,所以此处通过@TableField(condition = SqlCondition.LIKE)来实现动态组合查询条件,会根据前台传入的参数自动组合查询语句并进行分页。
* 字段填充策略 FieldFill
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190930153413988.png)
讲解如下:
实体类中有如下属性,通过上面的自动填充属性,我们可以实现在进行插入(insert)操作时对添加了注解@TableField(fill = FieldFill.INSERT)的字段进行自动填充(`解释:后面会写配置自动填充的配置类,该配置类的作用用于配置自动填充的值`)。
对添加了注解@TableField(fill = FieldFill.INSERT\_UPDATE)的字段在进行插入(insert)和更新(update)时进行自动填充。(`解释:后面会写配置自动填充的配置类,该配置类的作用用于配置自动填充的值`)。
~~~java
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private Long creatorId;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date gmtCreat;
/**
* 修改人
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long modifierId;
/**
* 修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
/**
* 是否可用
*/
@TableField(fill = FieldFill.INSERT)
private Boolean availableFlag;
~~~
这样我们在具体业务中对实体类进行赋值就可以不用对这些公共字段进行赋值,在执行插入或者更新时就能自动赋值并插入数据库。
那么要自动赋的值在哪里配置?
在项目的config包下新建自动填充处理类使其实现接口MetaObjectHandler,接下来我们来写自动赋值的配置类,并重写其方法:
~~~java
package com.ws.api.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 自动填充处理类
* @author badao
* @version 1.0
* @see
**/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override //在执行mybatisPlus的insert()时,为我们自动给某些字段填充值,这样的话,我们就不需要手动给insert()里的实体类赋值了
public void insertFill(MetaObject metaObject) {
//其中方法参数中第一个是前面自动填充所对应的字段,第二个是要自动填充的值。第三个是指定实体类的对象
this.setFieldValByName("modifierId", new Long(111), metaObject);
this.setFieldValByName("gmtModified", new Date(), metaObject);
this.setFieldValByName("creatorId", new Long(111), metaObject);
this.setFieldValByName("gmtCreat",new Date(), metaObject);
this.setFieldValByName("availableFlag",true, metaObject);
}
@Override//在执行mybatisPlus的update()时,为我们自动给某些字段填充值,这样的话,我们就不需要手动给update()里的实体类赋值了
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("modifierId", new Long(111), metaObject);
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
}
~~~
到此,@TableField完成字段自动填充的内容就讲完了
接下来我们来看@TableField(exist=false)的作用
比如在实体类中有一个属性为remark,但是在数据库中没有这个字段,但是在执行插入操作时给实体类的remark属性赋值了,那么可以通过在实体类的remark属性上添加
~~~java
@TableField(exist=false)
private String remark;
~~~
就不会报错了。