一、自定義類
自動填充功能-擴充MetaObjectHandler
//這塊一般會做成一個BaseEntity.java類
public class User {
@TableField(fill = FieldFill.INSERT_UPDATE)
private String operator;
}
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.strictInsertFill(metaObject, "operator", String.class, "Jetty");
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.strictUpdateFill(metaObject, "operator", String.class, "Tom");
}
}
this.strictUpdateFill(metaObject, "updateDatetime1", LocalDateTime.class, LocalDateTime.now())
.strictUpdateFill(metaObject, "updateDatetime", LocalDateTime.class, LocalDateTime.now());
類型處理器-擴充TypeHandler
@Data
@Accessors(chain = true)
@TableName(autoResultMap = true)
public class User {
private Long id;
private String name;
private Integer age;
private String email;
/**
* 注意!! 必須開啟映射注解
*
* @TableName(autoResultMap = true)
* <p>
* 以下兩種類型處理器,二選一 也可以同時存在
* <p>
* 注意!!選擇對應的 JSON 處理器也必須存在對應依賴包
*/
@TableField(typeHandler = WalletListTypeHandler.class)
private List<Wallet> wallets;
@TableField(typeHandler = FastjsonTypeHandler.class) //這是mybatis預設的
private OtherInfo otherInfo;
}
/**
* 自定義複雜類型處理器<br/>
* 不要問我為什麼要重寫 parse 因為頂層父類是無法擷取到準确的待轉換複雜傳回類型資料
*/
public class WalletListTypeHandler extends JacksonTypeHandler {
public WalletListTypeHandler(Class<?> type) {
super(type);
}
@Override
protected Object parse(String json) {
try {
return getObjectMapper().readValue(json, new TypeReference<List<Wallet>>() {
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
自定義ID生成器-擴充IdentifierGenerator
@Data
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
//下面這個類不需要配置,隻要用spring注解後,自動起作用
@Slf4j
@Component
public class CustomIdGenerator implements IdentifierGenerator {
private final AtomicLong al = new AtomicLong(1);
@Override
public Long nextId(Object entity) {
//可以将目前傳入的class全類名來作為bizKey,或者提取參數來生成bizKey進行分布式Id調用生成.
String bizKey = entity.getClass().getName();
log.info("bizKey:{}", bizKey);
MetaObject metaObject = SystemMetaObject.forObject(entity);
String name = (String) metaObject.getValue("name");
final long id = al.getAndAdd(1);
log.info("為{}生成主鍵值->:{}", name, id);
return id;
}
}
id BIGINT(20) NOT NULL COMMENT '主鍵ID',
---------------------以上适用用ID,下面的例子适用于string方式----------------------------------------
/**
* 字元串自增 ID
*/
@TableId(type = IdType.AUTO)
private String id;
id VARCHAR(30) AUTO_INCREMENT COMMENT '主鍵ID',
---------------------這個例子稍複雜一點,它可為各别表指定主鍵生成方式------------------------------------------
@Data
@KeySequence("SEQ_USER")
@TableName("user")
public class User {
@TableId(value = "id", type = IdType.INPUT)
private Long id;
}
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主鍵ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年齡',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',
PRIMARY KEY (id)
);
CREATE SEQUENCE IF NOT EXISTS SEQ_USER START WITH 10086 INCREMENT BY 1;
@Configuration
public class MpConfig {
@Bean
public GlobalConfig globalConfiguration() {
GlobalConfig conf = new GlobalConfig();
conf.setDbConfig(new GlobalConfig.DbConfig().setKeyGenerators(Arrays.asList(
// h2 1.x 的寫法(預設 2.x 的寫法)
new IKeyGenerator() {
@Override
public String executeSql(String incrementerName) {
return "select " + incrementerName + ".nextval";
}
@Override
public DbType dbType() {
return DbType.POSTGRE_SQL;
}
}
)));
return conf;
}
}
二、插件
動态擷取表名稱-DynamicTableNameInnerInterceptor插件
@Configuration
@MapperScan("com.baomidou.mybatisplus.samples.dytablename.mapper")
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
// 擷取參數方法
Map<String, Object> paramMap = RequestDataHelper.getRequestData();
paramMap.forEach((k, v) -> System.err.println(k + "----" + v));
String year = "_2018";
int random = new Random().nextInt(10);
if (random % 2 == 1) {
year = "_2019";
}
return tableName + year;
});
interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
// 3.4.3.2 廢棄該方式
// dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
return interceptor;
}
}
/**
* 請求參數傳遞輔助類
*/
public class RequestDataHelper {
/**
* 請求參數存取
*/
private static final ThreadLocal<Map<String, Object>> REQUEST_DATA = new ThreadLocal<>();
/**
* 設定請求參數
*
* @param requestData 請求參數 MAP 對象
*/
public static void setRequestData(Map<String, Object> requestData) {
REQUEST_DATA.set(requestData);
}
/**
* 擷取請求參數
*
* @param param 請求參數
* @return 請求參數 MAP 對象
*/
public static <T> T getRequestData(String param) {
Map<String, Object> dataMap = getRequestData();
if (CollectionUtils.isNotEmpty(dataMap)) {
return (T) dataMap.get(param);
}
return null;
}
/**
* 擷取請求參數
*
* @return 請求參數 MAP 對象
*/
public static Map<String, Object> getRequestData() {
return REQUEST_DATA.get();
}
}
@Test
void test() {
RequestDataHelper.setRequestData(new HashMap<String, Object>() {{
put("id", 123);
put("hello", "tomcat");
put("name", "湯姆凱特");
}});
// 自己去觀察列印 SQL 目前随機通路 user_2018 user_2019 表
for (int i = 0; i < 6; i++) {
User user = userMapper.selectById(1);
System.err.println(user.getName());
}
}
防止全表更新或删除操作-BlockAttackInnerInterceptor插件
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
樂觀鎖-OptimisticLockerInnerInterceptor插件
@Configuration
public class MybatisPlusOptLockerConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
@Data
public class User {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@Version
private Integer version; //注意這個version注解
}
分頁-PaginationInnerInterceptor插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
三、注解
邏輯删除-@TableLogic
@TableLogic
private Integer deleted; //deleted INT(11) NOT NULL DEFAULT 0,
@TableLogic(delval = "null", value = "1")
private Integer deleted;//deleted INT(11),
@TableLogic(delval = "now()", value = "null")
private LocalDateTime delTime; //del_time TIMESTAMP,
實體映射-@ResultMap
@ResultMap("userChildrenMap")
@Select("<script>select u.id,u.name,u.email,u.age,c.id as \"c_id\",c.name as \"c_name\",c.user_id as \"c_user_id\" " +
"from user u " +
"left join children c on c.user_id = u.id " +
"<where>" +
"<if test=\"selectInt != null\"> " +
"and u.age = #{selectInt} " +
"</if> " +
"<if test=\"selectStr != null and selectStr != ''\"> " +
"and c.name = #{selectStr} " +
"</if> " +
"</where>" +
"</script>")
MyPage<UserChildren> userChildrenPage(MyPage<UserChildren> myPage);
<resultMap id="userChildrenMap" type="com.baomidou.mybatisplus.samples.pagination.model.UserChildren">
<id column="id" property="id"/>
<result column="age" property="age"/>
<result column="email" property="email"/>
<result column="name" property="name"/>
<collection property="c" ofType="com.baomidou.mybatisplus.samples.pagination.entity.Children" columnPrefix="c_">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="user_id" property="userId"/>
</collection>
</resultMap>
@Data
@TableName(resultMap = "m_b") // 對應xml裡的 id
-----------------------------------------------
public class Man {}
<resultMap id="m_b" type="com.baomidou.mybatisplus.samples.resultmap.entity.Man">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="laoPoId" column="lao_po_id"/>
</resultMap>
-----------------------------------------------
<select id="selectLinkById" resultMap="m_r">
select *
from man
where id = #{id}
</select>