MyBatis-Plus进阶之常用注解

前言

我们在使用MyBatis-Plus时,会使用相应的MyBatis-Plus注解,可以让我们事半功倍,下面介绍一些MP常用的注解。


@TableName

描述:表名注解

如果我们的实体类名和表名不一致,那么我们就需要在实体类上配置@TableName注解,如果一致的话可以不加该注解

例:

@TableName("my_user")
public class User {
}

源码如下:


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface TableName {

    /**
     * 实体对应的表名
     */
    String value() default "";

    /**
     * schema
     *
     * @since 3.1.1
     */
    String schema() default "";

    /**
     * 是否保持使用全局的 tablePrefix 的值
     * <p> 只生效于 既设置了全局的 tablePrefix 也设置了上面 {@link #value()} 的值 </p>
     * <li> 如果是 false , 全局的 tablePrefix 不生效 </li>
     *
     * @since 3.1.1
     */
    boolean keepGlobalPrefix() default false;

    /**
     * 实体映射结果集,
     * 只生效与 mp 自动注入的 method
     */
    String resultMap() default "";

    /**
     * 是否自动构建 resultMap 并使用,
     * 只生效与 mp 自动注入的 method,
     * 如果设置 resultMap 则不会进行 resultMap 的自动构建并注入,
     * 只适合个别字段 设置了 typeHandler 或 jdbcType 的情况
     *
     * @since 3.1.2
     */
    boolean autoResultMap() default false;

    /**
     * 需要排除的属性名
     *
     * @since 3.3.1
     */
    String[] excludeProperty() default {};
}

关于autoResultMap的说明:

mp会自动构建一个ResultMap并注入到mybatis里(一般用不上).下面讲两句: 因为mp底层是mybatis,所以一些mybatis的常识你要知道,mp只是帮你注入了常用crud到mybatis里 注入之前可以说是动态的(根据你entity的字段以及注解变化而变化),但是注入之后是静态的(等于你写在xml的东西) 而对于直接指定typeHandler,mybatis只支持你写在2个地方:

1、定义在resultMap里,只作用于select查询的返回结果封装

2、定义在insert和updatesql的#{property}里的property后面(:#{property,typehandler=xxx.xxx.xxx}),只作用于设置值 而除了这两种直接指定typeHandler,mybatis有一个全局的扫描你自己的typeHandler包的配置,这是根据你的property的类型去找typeHandler并使用.

@TableId

描述:主键注解

我们可以在@TableId配置主键生成的类型

例:

@TableId(type = IdType.AUTO)
private Long id

;源码:

/**
 * 表主键标识
 *
 * @author hubin
 * @since 2016-01-23
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {

    /**
     * 字段值(驼峰命名方式,该值可无)
     */
    String value() default "";

    /**
     * 主键ID类型
     * {@link IdType}
     */
    IdType type() default IdType.NONE;
}

IdType类型有以下几种

AUTO		数据库ID自增
NONE		无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUT		insert前自行set主键值
ASSIGN_ID	分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID	分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)

@TableField

描述:字段注解(非主键)

我们在对某个字段进行定制化处理时,就可以使用@TableField注解

例:

    @TableField(value = "name",updateStrategy = FieldStrategy.IGNORED)
    private String name;

源码如下:

public @interface TableField {

    /**
     * 数据库字段值,
     * 不需要配置该值的情况:
     * <li> 当 {@link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} 为 true 时,
     * (mp下默认是true,mybatis默认是false), 数据库字段值.replace("_","").toUpperCase() == 实体属性名.toUpperCase() </li>
     * <li> 当 {@link com.baomidou.mybatisplus.core.MybatisConfiguration#mapUnderscoreToCamelCase} 为 false 时,
     * 数据库字段值.toUpperCase() == 实体属性名.toUpperCase()</li>
     */
    String value() default "";

    /**
     * 是否为数据库表字段
     * 默认 true 存在,false 不存在
     */
    boolean exist() default true;

    /**
     * 字段 where 实体查询比较条件
     * 默认 `=` 等值
     */
    String condition() default "";

    /**
     * 字段 update set 部分注入, 该注解优于 el 注解使用
     * <p>
     * 例1:@TableField(.. , update="%s+1") 其中 %s 会填充为字段
     * 输出 SQL 为:update 表 set 字段=字段+1 where ...
     * <p>
     * 例2:@TableField(.. , update="now()") 使用数据库时间
     * 输出 SQL 为:update 表 set 字段=now() where ...
     */
    String update() default "";

    /**
     * 字段验证策略之 insert: 当insert操作时,该字段拼接insert语句时的策略
     * IGNORED: 直接拼接 insert into table_a(column) values (#{columnProperty});
     * NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
     * NOT_EMPTY: insert into table_a(<if test="columnProperty != null and columnProperty!=''">column</if>) values (<if test="columnProperty != null and columnProperty!=''">#{columnProperty}</if>)
     *
     * @since 3.1.2
     */
    FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段验证策略之 update: 当更新操作时,该字段拼接set语句时的策略
     * IGNORED: 直接拼接 update table_a set column=#{columnProperty}, 属性为null/空string都会被set进去
     * NOT_NULL: update table_a set <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: update table_a set <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     *
     * @since 3.1.2
     */
    FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段验证策略之 where: 表示该字段在拼接where条件时的策略
     * IGNORED: 直接拼接 column=#{columnProperty}
     * NOT_NULL: <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     *
     * @since 3.1.2
     */
    FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;

    /**
     * 字段自动填充策略
     */
    FieldFill fill() default FieldFill.DEFAULT;

    /**
     * 是否进行 select 查询
     * <p>大字段可设置为 false 不加入 select 查询范围</p>
     */
    boolean select() default true;

    /**
     * 是否保持使用全局的 Format 的值
     * <p> 只生效于 既设置了全局的 Format 也设置了上面 {@link #value()} 的值 </p>
     * <li> 如果是 false , 全局的 Format 不生效 </li>
     *
     * @since 3.1.1
     */
    boolean keepGlobalFormat() default false;

    /**
     * JDBC类型 (该默认值不代表会按照该值生效),
     * 只生效与 mp 自动注入的 method,
     * 建议配合 {@link TableName#autoResultMap()} 一起使用
     * <p>
     * {@link ResultMapping#jdbcType} and {@link ParameterMapping#jdbcType}
     *
     * @since 3.1.2
     */
    JdbcType jdbcType() default JdbcType.UNDEFINED;

    /**
     * 类型处理器 (该默认值不代表会按照该值生效),
     * 只生效与 mp 自动注入的 method,
     * 建议配合 {@link TableName#autoResultMap()} 一起使用
     * <p>
     * {@link ResultMapping#typeHandler} and {@link ParameterMapping#typeHandler}
     *
     * @since 3.1.2
     */
    Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;

    /**
     * 指定小数点后保留的位数,
     * 只生效与 mp 自动注入的 method,
     * 建议配合 {@link TableName#autoResultMap()} 一起使用
     * <p>
     * {@link ParameterMapping#numericScale}
     *
     * @since 3.1.2
     */
    String numericScale() default "";
}

FieldStrategy(字段验证策略)

值			描述
IGNORED		忽略判断
NOT_NULL	非NULL判断
NOT_EMPTY	非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
DEFAULT		追随全局配置

FieldFill(字段自动填充策略)

值			描述
DEFAULT		默认不处理
INSERT		插入时填充字段
UPDATE		更新时填充字段
INSERT_UPDATE	插入和更新时填充字段

关于jdbcTypetypeHandler以及numericScale的说明:

numericScale只生效于 update 的sql. jdbcType和typeHandler如果不配合@TableName#autoResultMap = true一起使用,也只生效于 update 的sql. 对于typeHandler如果你的字段类型和set进去的类型为equals关系,则只需要让你的typeHandler让Mybatis加载到即可,不需要使用注解

@Version

描述:乐观锁注解、标记 @Verison 在字段上

例:

   @Version
   private Integer version;

@EnumValue

描述:通枚举类注解(注解在枚举字段上)


@TableLogic

描述:表字段逻辑处理注解(逻辑删除)

属性		类型		必须指定	默认值	描述
value	String		否	""		逻辑未删除值
delval	String		否	""		逻辑删除值

例:

@TableLogic(value = "0",delval = "1")
private String isDelete;

效果:
没有@TableLogic注解调用deleteById/removeById,直接删除数据。

SQL:delete from table where id = 1
 有注解走Update方法

 SQL:Update table set isDelete = 1 where id = 1

并且update方法是不会将该字段放入修改字段中的

@KeySequence

描述:序列主键策略

属性		类型	必须指定	默认值		描述
value	String	否	""			序列名
clazz	Class	否	Long.class	id的类型, 可以指定String.class,这样返回的Sequence值是字符串"1"

例:

@KeySequence(value="seq_user",clazz=String.class) //value为数据库中生成的序列名,class指主键属性类型
public class User {
     @TableId(type=IdType.INPUT)  //注意主键类型要指定为Input
     private String id;

本质:

其实在Oracle数据库中进行新增数据首先在数据库中先执行

select seq_user.nextval from dual;这样获取下一个主键的序列,然后再执行插入操作

另外:

实际开发中可能会有很多个实体类,所以在每个实体类上都加上@KeySequence,显得很繁琐

假如需要多个实体公用同一个序列

可以将@keySequence 定义在父类中, 可实现多个子类对应的多个表公用一个 Sequence

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值