在框架的使用中,注解约定大于配置,我们可以轻松通过注解完成很多工作,比如字段改名映射,插入更新的时间写入等,下面的学习内容主要列举了常用的注解。
我们看看官网中列出的注解有哪些[1]:
本文的注解学习主要内容集中在以下的注解中:
- @TableName
- @TableId
- @TableField
- @EnumValue
- @Version
- @TableLogic
环境:
- Mybatis-Plus: 3.5.5
@TableName
先看看源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface TableName {
String value() default "";
String schema() default "";
boolean keepGlobalPrefix() default false;
String resultMap() default "";
boolean autoResultMap() default false;
String[] excludeProperty() default {};
}
开放的功能很多,我们平时可能并用不到,主要需要注意的是 value
, 我们通过设置 value = "table_xxx"
,注解加在实体类上,映射实体类和数据库表的表名。
@TableId
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {
String value() default "";
IdType type() default IdType.NONE;
}
注解字段的,通过设置 value
声明在数据库表的字段名,通过 type
属性声明用哪种类型的命名策略,常见的策略有:
比如我们常用的自增主键,或者通过指定id,默认使用微博开源的雪花算法生成id,全局唯一且自增id,即:
@TableId(type = IdType.AUTO)
@TableId(type = IdType.ASSIGN_ID)
@TableField
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableField {
String value() default "";
boolean exist() default true;
String condition() default "";
String update() default "";
FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;
FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;
FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;
FieldFill fill() default FieldFill.DEFAULT;
boolean select() default true;
boolean keepGlobalFormat() default false;
String property() default "";
JdbcType jdbcType() default JdbcType.UNDEFINED;
Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
boolean javaType() default false;
String numericScale() default "";
}
该注解提供的功能很多,这里讲几个常用的。
value
通过设置该值,对应到数据库表的字段名。
condition
设定值,进而是否开启如模糊查询。
exist
主要指明字段在不在数据库表中,如果 false 则不在数据库表中。
select
注明查到的字段是否要出现在返回结果中,某些场景中,如 User 表中,可能有 password ,对于这种敏感的字段,是不是可以不用返回呢。
fill
这里涉及自动填充,在哪些场景中会用到呢,如 插入、更新、更改的时间,我们希望自动填入,其原理其实也是通过设置实体的值,进而达到自动填入的功能。
填入时机:
如果设置了该 fill 属性,则我们需要去实现或者继承 MetaObjectHandler
接口:
package com.example.springbootmybatisplusdemo.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDateTime;
@Configuration
@MapperScan(basePackages = "com.example.springbootmybatisplusdemo.mapper")
public class AutoTimeConfig implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
// method 1
this.strictInsertFill(metaObject, "created", () -> LocalDateTime.now(), LocalDateTime.class);
this.strictInsertFill(metaObject, "modified", () -> LocalDateTime.now(), LocalDateTime.class);
// method 2
// setFieldValByName("created", LocalDateTime.now(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updated", () -> LocalDateTime.now(), LocalDateTime.class);
}
}
在上面的实现中,我们实现了 insertFill/updateFill
两个方法,另外对于字段值的填充,在代码中也注明了2种方法。
@EnumValue
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface EnumValue {
}
这里的使用上,我们需要加到会在数据库表中显示的字段上,比如我们的实体类:
private GenderEnum gender;
GenderEnum 是一个枚举类:
package com.example.springbootmybatisplusdemo.entity;
import com.baomidou.mybatisplus.annotation.EnumValue;
public enum GenderEnum {
Male(1, "Male"),
Female(0, "Female");
@EnumValue
private final int code;
private final String desc;
GenderEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
}
通过上述的配置,我们就可以在设置 gender
字段时,通过 GenderEnum
枚举类给定 Male或者Female
,最后写入数据库表时,实际是写入的 code 的值,注意我们声明的 1 -> Male,0 -> Female
,所以在数据库表中,gender
实际填入的值是 0/1
。
@Value
该注解主要用于乐观锁,结合拦截件使用:
package com.example.springbootmybatisplusdemo.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.example.springbootmybatisplusdemo.mapper")
public class MybatisPlusConfig {
// register 乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
测试:
package com.example.springbootmybatisplusdemo.test;
import com.example.springbootmybatisplusdemo.entity.UserDemo;
import com.example.springbootmybatisplusdemo.mapper.UserDemoMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class optimisticLockTest {
@Autowired
private UserDemoMapper userMapper;
@Test
public void lockTest() {
UserDemo user1 = new UserDemo();
user1.setId(100L);
user1.setVersion(1);
UserDemo user2 = new UserDemo();
user2.setId(100L);
user2.setVersion(1);
userMapper.updateById(user1); // ok
userMapper.updateById(user2); // fail
}
}
@TableLogic
该注解用于逻辑删除,真删除是删除数据库表中的记录行,逻辑删除则是标记某个字段的值,如:
@TableLogic(value = "0", delval = "1")
private Integer deleted;
其中 value
是原值,delval
是删除后填入的值,如删除前,deleted为0,删除后deleted为1,我们在查询数据时注意下这个字段即可。
demo
以下是以上注解在 case 中的使用:
package com.example.springbootmybatisplusdemo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName(value = "user_demo") // tableName
public class UserDemo {
@TableId(type = IdType.AUTO) // tableId,自增类型,主键
private Long id;
@TableId(type = IdType.ASSIGN_ID) // 该策略使用接口IdentifierGenerator的方法nextId(以实现类为DefaultIdentifierGenerator雪花算法)
private Long myId;
@TableField(value = "name", condition = SqlCondition.LIKE) // tableField,开启模糊查询
private String username;
@TableField(exist = false) // 指明字段不在数据表中
private String username1;
@TableField(select = false) // 字段不出现在返回结果中
private String password;
@TableField(fill = FieldFill.INSERT) // 如果继承接口,已经实现了insertFill,需要实现 MetaObjectHandler,见AutoTimeConfig
private LocalDateTime created;
@TableField(fill = FieldFill.UPDATE) // 需要实现 MetaObjectHandler
private LocalDateTime updated;
@TableField(fill = FieldFill.INSERT_UPDATE) // 需要实现 MetaObjectHandler
private LocalDateTime modified;
private GenderEnum gender; // enumValue
@Version
private Integer version; // version,乐观锁,集合配置使用,如拦截件
@TableLogic(value = "0", delval = "1") // 逻辑删除,其实就是更新delete字段的值,0 -> 1, update table_name set deleted=1 where xxx=yyy, or delete from table_name where xxx=yyy
private Integer deleted;
}
参考:
标签:String,default,private,Plus,import,Mybatis,注解,com,public From: https://www.cnblogs.com/davis12/p/17933803.html