MyBatisPlus總結

MyBatis-Plus時Mybatis的Best Partner

MyBatis-Plus?(opens new window)(簡稱 MP)是一個?MyBatis?(opens new window)的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。

特性

  • 無侵入
  • 損耗小
  • 強大的 CRUD 操作
  • 支持 Lambda 形式調用
  • 支持主鍵自動生成
  • 支持 ActiveRecord 模式
  • 支持自定義全局通用操作
  • 內置代碼生成器
  • 內置分頁插件
  • 分頁插件支持多種數據庫
  • 內置性能分析插件
  • 內置全局攔截插件

#支持數據庫

框架結構

引入?MyBatis-Plus?之后請不要再次引入?MyBatis?以及?mybatis-spring-boot-starter和MyBatis-Spring,以避免因版本差異導致的問題

注解

@TableName

描述:表名注解,標識實體類對應的表

使用位置:實體類

注意: 默認是以對象名為表名,可以配置全局配置名字增加前綴,

也可以用@TableName進行注釋表名,如下(同時配置,注解生效)

。@TableName("sys_user") public class User { private Long id; private String name; private Integer age; private String email; }

屬性

類型

必須指定

默認值

描述

value

String

""

表名

schema

String

""

schema

keepGlobalPrefix

boolean

false

是否保持使用全局的 tablePrefix 的值(當全局 tablePrefix 生效時)

resultMap

String

""

xml 中 resultMap 的 id(用于滿足特定類型的實體類對象綁定)

autoResultMap

boolean

false

是否自動構建 resultMap 并使用(如果設置 resultMap 則不會進行 resultMap 的自動構建與注入)

excludeProperty

String[]

{}

需要排除的屬性名

@since 3.3.1

關于?autoResultMap?的說明:

MP 會自動構建一個?resultMap?并注入到 MyBatis 里(一般用不上),請注意以下內容:

因為 MP 底層是 MyBatis,所以 MP 只是幫您注入了常用 CRUD 到 MyBatis 里,注入之前是動態的(根據您的 Entity 字段以及注解變化而變化),但是注入之后是靜態的(等于 XML 配置中的內容)。

而對于?typeHandler?屬性,MyBatis 只支持寫在 2 個地方:

  1. 定義在 resultMap 里,作用于查詢結果的封裝
  2. 定義在?insert??update??#{property}??property?#{property,typehandler=xxx.xxx.xxx}?設置值

除了以上兩種直接指定?typeHandler?的形式,MyBatis 有一個全局掃描自定義?typeHandler?包的配置,原理是根據您的?property?類型去找其對應的?typeHandler?并使用。

@TableId

描述:主鍵注解

使用位置:實體類主鍵字段

@TableName("sys_user") public class User { @TableId private Long id; private String name; private Integer age; private String email; }

屬性

類型

必須指定

默認值

描述

value

String

""

主鍵字段名

type

Enum

IdType.NONE

指定主鍵類型(在不寫type類型的時候默認為雪花算法)

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 方法)

ID_WORKER

分布式全局唯一 ID 長整型類型(pleaseuseASSIGN_ID)

UUID

32 位 UUID 字符串(please use

ASSIGN_UUID

)

ID_WORKER_STR

分布式全局唯一 ID 字符串類型(please use

ASSIGN_ID

)

@TableField

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

@TableName("sys_user") public class User { @TableId private Long id; @TableField("nickname") private String name; private Integer age; private String email; }

屬性

類型

必須指定

默認值

描述

value

String

""

數據庫字段名

exist

boolean

true

是否為數據庫表字段

condition

String

""

字段

where

實體查詢比較條件,有值設置則按設置的值為準,沒有則為默認全局的

%s=#{%s}

參考

@Version

描述:樂觀鎖注解,標記@version在字段上

@EnumValue

描述:普通枚舉類注解(標注在枚舉字段上)

@TableLogic

描述:表字段邏輯處理注解(邏輯刪除)

屬性

類型

必須指定

默認值

描述

value

String

""

邏輯未刪除值

delval

String

""

邏輯刪除值

@OrderBy

描述:內置Sql默認指定排序,優先級低于wrapper條件查詢

屬性

類型

必須指定

默認值

描述

asc

boolean

true

是否倒序查詢

sort

short

Short.MAX_VALUE

數字越小越靠前

@Mapper

寫在Dao類上,將類注入Spring容器中

@MapperScan()

@MapperScan(value = {"com.aqiuo.dao"})

寫在啟動類上,將需要掃描的包寫在value中

CRUD接口

Service CRUD 接口

說明: 通用 Service CRUD 封裝IService (opens new window)

  • get 查詢單行 remove 刪除
  • list 查詢集合
  • page 分頁
  • Mapper 泛型 T 為任意實體對象 建議如果存在自定義通用 Service 方法的可能,
  • 請創建自己的 IBaseService 基礎 Mybatis-Plus 的基類 對象 Wrapper 為 條件構造器

save

// 插入一條記錄(選擇字段,策略插入) boolean save(T entity); // 插入(批量) boolean saveBatch(Collection<T> entityList); // 插入(批量) boolean saveBatch(Collection<T> entityList, int batchSize);

參數說明

類型

參數名

描述

T

entity

實體對象

Collection

entityList

實體對象集合

int

batchSize

插入批次數量

SaveOrUpdate

// TableId 注解存在更新記錄,否插入一條記錄,
//如果有這個記錄,則修改記錄,如果沒有就插入記錄
//如果沒有id就是插入,有就是修改
boolean saveOrUpdate(T entity);
// 根據updateWrapper嘗試更新,否繼續執行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

參數說明

類型

參數名

描述

T

entity

實體對象

Wrapper

updateWrapper

實體對象封裝操作類 UpdateWrapper

Collection

entityList

實體對象集合

int

batchSize

插入批次數量

Remove

// 根據 queryWrapper 設置的條件,刪除記錄
boolean remove(Wrapper<T> queryWrapper);
// 根據 ID 刪除
boolean removeById(Serializable id);
// 根據 columnMap 條件,刪除記錄(map存的條件)
boolean removeByMap(Map<String, Object> columnMap);
// 刪除(根據ID 批量刪除)
boolean removeByIds(Collection<? extends Serializable> idList);

參數說明

類型

參數名

描述

Wrapper

queryWrapper

實體包裝類 QueryWrapper

Serializable

id

主鍵 ID

Map

columnMap

表字段 map 對象

Collection

idList

主鍵 ID 列表

Update

(注意updateById才能根據id修改內容,其他的要用wrapper)

// 根據 UpdateWrapper 條件,更新記錄 需要設置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根據 whereWrapper 條件,更新記錄
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根據 ID 選擇修改
boolean updateById(T entity);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

參數說明

類型

參數名

描述

Wrapper

updateWrapper

實體對象封裝操作類 UpdateWrapper

T

entity

實體對象

Collection

entityList

實體對象集合

int

batchSize

更新批次數量

Get

// 根據 ID 查詢
T getById(Serializable id);
// 根據 Wrapper,查詢一條記錄。結果集,如果是多個會拋出異常,隨機取一條加上限制條件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據 Wrapper,查詢一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

參數說明

類型

參數名

描述

Serializable

id

主鍵 ID

Wrapper

queryWrapper

實體對象封裝操作類 QueryWrapper

boolean

throwEx

有多個 result 是否拋出異常

T

entity

實體對象

Function

mapper

轉換函數

List

// 查詢所有
List<T> list();
// 查詢列表
List<T> list(Wrapper<T> queryWrapper);
// 查詢(根據ID 批量查詢)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查詢(根據 columnMap 條件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查詢所有列表
List<Map<String, Object>> listMaps();
// 查詢列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查詢全部記錄
List<Object> listObjs();
// 查詢全部記錄
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根據 Wrapper 條件,查詢全部記錄
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

參數說明

類型

參數名

描述

Wrapper

queryWrapper

實體對象封裝操作類 QueryWrapper

Collection

idList

主鍵 ID 列表

Map

columnMap

表字段 map 對象

Function

mapper

轉換函數

Page

// 無條件分頁查詢
IPage<T> page(IPage<T> page);
// 條件分頁查詢
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 無條件分頁查詢
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 條件分頁查詢
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

參數說明

類型

參數名

描述

IPage

page

翻頁對象

Wrapper

queryWrapper

實體對象封裝操作類 QueryWrapper

Count

// 查詢總記錄數 int count(); // 根據 Wrapper 條件,查詢總記錄數 int count(Wrapper<T> queryWrapper);

參數說明

類型

參數名

描述

Wrapper

queryWrapper

實體對象封裝操作類 QueryWrapper

Chain

query (返回值類型是lanmdateQuery)

(存在有一個靜態方法引用非靜態方法的問題)

// 鏈式查詢 普通
QueryChainWrapper<T> query();
// 鏈式查詢 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();
update(返回值是LamdaQueryWrapper)
// 鏈式更改 普通
UpdateChainWrapper<T> update();
// 鏈式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();// 示例:
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);

Mapper CRUD 接口

說明: 通用 CRUD 封裝BaseMapper接口,為Mybatis-Plus啟動時自動解析實體表關系映射轉換為Mybatis內部對象注入容器 泛型 T 為任意實體類對象 參數 Serializable為任意類型的主鍵,Mybatis-Plus不推薦使用復合主鍵約定每一張表都有自己唯一的id主鍵 對象Wrapper 條件構造器

Insert

// 插入一條記錄 int insert(T entity);

參數說明

類型

參數名

描述

T

entity

實體對象

Delete

// 根據 entity 條件,刪除記錄 int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper); // 刪除(根據ID 批量刪除) int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 根據 ID 刪除 int deleteById(Serializable id); // 根據 columnMap 條件,刪除記錄 int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

參數說明

類型

參數名

描述

Wrapper

wrapper

實體對象封裝操作類(可以為 null)

Collection

idList

主鍵 ID 列表(不能為 null 以及 empty)

Serializable

id

主鍵 ID

Map

columnMap

表字段 map 對象

Update

// 根據 whereWrapper 條件,更新記錄 int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper); // 根據 ID 修改 int updateById(@Param(Constants.ENTITY) T entity);

使用提示:

在調用updateById方法前,需要在T entity(對應的實體類)中的主鍵屬性上加上@TableId注解。

參數說明

類型

參數名

描述

T

entity

實體對象 (set 條件值,可為 null)

Wrapper

updateWrapper

實體對象封裝操作類(可以為 null,里面的 entity 用于生成 where 語句)

Select

// 根據 ID 查詢 T selectById(Serializable id); // 根據 entity 條件,查詢一條記錄 T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢(根據ID 批量查詢) List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList); // 根據 entity 條件,查詢全部記錄 List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 查詢(根據 columnMap 條件) List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap); // 根據 Wrapper 條件,查詢全部記錄 List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根據 Wrapper 條件,查詢全部記錄。注意: 只返回第一個字段的值 List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根據 entity 條件,查詢全部記錄(并翻頁) IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根據 Wrapper 條件,查詢全部記錄(并翻頁) IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper); // 根據 Wrapper 條件,查詢總記錄數 Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

參數說明

類型

參數名

描述

Serializable

id

主鍵 ID

Wrapper

queryWrapper

實體對象封裝操作類(可以為 null)

Collection

idList

主鍵 ID 列表(不能為 null 以及 empty)

Map

columnMap

表字段 map 對象

IPage

page

分頁查詢條件(可以為 RowBounds.DEFAULT)

條件構造器

說明:

  • 以下出現的第一個入參 boolean condition 表示該條件是否加入最后生成的sql語句中,例如:
    • query.like(StringUtils.isNotBlank(name),Entity::getName,name).eq(age!=null && age>=0,Entity::getAge,age)
  • 以下代碼塊內的多個方法均從上往下補全個別 boolean 類別的入參,默認為 true
  • 以下方法在入參中出現的 R 為泛型,在普通wrapper中 是String, 在 LambdaWrapper 中是函數
    • 例如: Entity::getId,Entity 為實體類,getId 為字段 id 的getter Method)
  • 以下方法入參中的 R column 均為數據庫字段,當 R 具體類型為 String 時則為數據庫字段名(字段名是數據庫關鍵字的自己用轉義符包裹!)
  • 以下舉例均為使用普通wrapper ,入參為Map 和List 的均以json形式表現!
  • 如果入參的Map或者List為空,則不會加入最后生成的SQL中!!!

警告

  1. wrapper 很重
  2. 傳輸 wrapper 可以類比為你的 controller 用 map 接收值(開發一時爽,維護火葬場)
  3. 正確的 RPC 調用姿勢是寫一個 DTO 進行傳輸,被調用方再根據 DTO 執行相應的操作
  4. 我們拒絕接受任何關于 RPC 傳輸 Wrapper 報錯相關的 issue 甚至 pr

AbstractWrapper

說明:

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父類

用于生成 sql 的 where 條件, entity 屬性也用于生成 sql 的 where 條件

注意: entity 生成的 where 條件與 使用各個 api 生成的 where 條件沒有任何關聯行為

allEq

allEq(Map<R, V> params) allEq(Map<R, V> params, boolean null2IsNull) allEq(boolean condition, Map<R, V> params, boolean null2IsNull)

全部eq(或個別isNull)

個別參數說明:

  • params : key 為數字庫字段名 value為 字段值
  • null2IsNull: 為true,則 在 map 的value為null時調用isNull方法,為false,則忽略value的值為null的

例一:allEq({id:1,name:"老王",age:null}) --->id = 1 and name = '老王' and age is null

例二:allEq({id:1,name:"老王",age:null}, false)-->id = 1 and name = '老王'

eq

eq(R column, Object val) eq(boolean condition, R column, Object val)

等于 =

例:?eq("name", "老王") - --> name = '老王'

ne

ne(R column, Object val) ne(boolean condition, R column, Object val)

不等于 <>

例: ne("name", "老王") ---> name <> '老王'

gt

gt(R column, Object val) gt(boolean condition, R column, Object val)

  • 大于 >
  • 例:gt("age",18) - - -> age>18

ge

ge(R column, Object val) ge(boolean condition, R column, Object val)

  • 大于等于 >=
  • 例:?ge("age", 18) --> age >= 18

lt

lt(R column, Object val) lt(boolean condition, R column, Object val)

  • 小于
  • 例:?lt("age", 18)--->age < 18

#le

le(R column, Object val) le(boolean condition, R column, Object val)

  • 小于等于
  • 例:?le("age", 18)--->age

#between

between(R column, Object val1, Object val2) between(boolean condition, R column, Object val1, Object val2)

  • BETWEEN 值1 AND 值2
  • 例:?between("age", 18, 30)--->age between 18 and 30

#notBetween

notBetween(R column, Object val1, Object val2) notBetween(boolean condition, R column, Object val1, Object val2)

  • NOT BETWEEN 值1 AND 值2
  • 例:?notBetween("age", 18, 30)--->age not between 18 and 30

#like

like(R column, Object val) like(boolean condition, R column, Object val)

  • LIKE '%值%'
  • 例:?like("name", "王")--->name like '%王%'

#notLike

notLike(R column, Object val) notLike(boolean condition, R column, Object val)

  • NOT LIKE '%值%'
  • 例:?notLike("name", "王")--->name not like '%王%'

#likeLeft

likeLeft(R column, Object val) likeLeft(boolean condition, R column, Object val)

  • LIKE '%值'
  • 例:?likeLeft("name", "王")--->name like '%王'

likeRight

likeRight(R column, Object val) likeRight(boolean condition, R column, Object val)

  • LIKE '值%'
  • 例:?likeRight("name", "王")--->name like '王%'

notLikeLeft

notLikeLeft(R column, Object val) notLikeLeft(boolean condition, R column, Object val)

  • NOT LIKE '%值'
  • 例:?notLikeLeft("name", "王")--->name not like '%王'

notLikeRight

notLikeRight(R column, Object val) notLikeRight(boolean condition, R column, Object val)

  • NOT LIKE '值%'
  • 例:?notLikeRight("name", "王")--->name not like '王%'

#isNull

isNull(R column) isNull(boolean condition, R column)

  • 字段 IS NULL
  • 例:?isNull("name")--->name is null

isNotNull

isNotNull(R column) isNotNull(boolean condition, R column)

  • 字段 IS NOT NULL
  • 例:?isNotNull("name")--->name is not null

in

in(R column, Collection<?> value) in(boolean condition, R column, Collection<?> value)

  • 字段 IN (value.get(0), value.get(1), ...)
  • 例:?in("age",{1,2,3})--->age in (1,2,3)

in(R column, Object... values) in(boolean condition, R column, Object... values)

  • 字段 IN (v0, v1, ...)
  • 例:?in("age", 1, 2, 3)--->age in (1,2,3)

notIn

notIn(R column, Collection<?> value) notIn(boolean condition, R column, Collection<?> value)

  • 字段 NOT IN (value.get(0), value.get(1), ...)
  • 例:?notIn("age",{1,2,3})-->age not in (1,2,3)

notIn(R column, Object... values) notIn(boolean condition, R column, Object... values)

  • 字段 NOT IN (v0, v1, ...)
  • 例:?notIn("age", 1, 2, 3)--->age not in (1,2,3)

inSql

inSql(R column, String inValue) inSql(boolean condition, R column, String inValue)

  • 字段 IN ( sql語句 )
  • 例:?inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
  • 例:?inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)

notInSql

notInSql(R column, String inValue) notInSql(boolean condition, R column, String inValue)

  • 字段 NOT IN ( sql語句 )
  • 例:?notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
  • 例:?notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)

groupBy

groupBy(R... columns) groupBy(boolean condition, R... columns)

  • 分組:GROUP BY 字段, ...
  • 例:?groupBy("id", "name")--->group by id,name

orderByAsc

orderByAsc(R... columns) orderByAsc(boolean condition, R... columns)

  • 排序:ORDER BY 字段, ... ASC
  • 例:?orderByAsc("id", "name")--->order by id ASC,name ASC

orderByDesc

orderByDesc(R... columns) orderByDesc(boolean condition, R... columns)

  • 排序:ORDER BY 字段, ... DESC
  • 例:?orderByDesc("id", "name")--->order by id DESC,name DESC

orderBy

orderBy(boolean condition, boolean isAsc, R... columns)

  • 排序:ORDER BY 字段, ...
  • 例:?orderBy(true, true, "id", "name")--->order by id ASC,name ASC

having

having(String sqlHaving, Object... params) having(boolean condition, String sqlHaving, Object... params)

  • HAVING ( sql語句 )
  • 例:?having("sum(age) > 10")--->having sum(age) > 10
  • 例:?having("sum(age) > {0}", 11)--->having sum(age) > 11

func

func(Consumer<Children> consumer) func(boolean condition, Consumer<Children> consumer)

  • func 方法(主要方便在出現if...else下調用不同方法能不斷鏈)
  • 例:?func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})

or

or() or(boolean condition)

  • 拼接 OR

注意事項:

主動調用or表示緊接著下一個方法不是用and連接!(不調用or則默認為使用and連接)

  • 例:?eq("id",1).or().eq("name","老王") --->id = 1 or name = '老王'

or(Consumer<Param> consumer) or(boolean condition, Consumer<Param> consumer)

  • OR 嵌套
  • 例:?or(i -> i.eq("name", "李白").ne("status", "活著"))--->or (name = '李白' and status <> '活著')

and

and(Consumer<Param> consumer) and(boolean condition, Consumer<Param> consumer)

  • AND 嵌套
  • 例:?and(i -> i.eq("name", "李白").ne("status", "活著"))--->and (name = '李白' and status <> '活著')

nested

nested(Consumer<Param> consumer) nested(boolean condition, Consumer<Param> consumer)

  • 正常嵌套 不帶 AND 或者 OR
  • 例:?nested(i -> i.eq("name", "李白").ne("status", "活著")) --->(name = '李白' and status <> '活著')

apply

apply(String applySql, Object... params) apply(boolean condition, String applySql, Object... params)

  • 拼接 sql
    • 注意事項:

該方法可用于數據庫函數?動態入參的params對應前面applySql內部的{index}部分.這樣是不會有sql注入風險的,反之會有!

  • 例:?apply("id = 1") id = 1
  • 例:?apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  • 例:?apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

last

last(String lastSql) last(boolean condition, String lastSql)

  • 無視優化規則直接拼接到 sql 的最后

注意事項:

只能調用一次,多次調用以最后一次為準 有sql注入的風險,請謹慎使用

  • 例:?last("limit 1")

exists

exists(String existsSql) exists(boolean condition, String existsSql)

  • 拼接 EXISTS ( sql語句 )
  • 例:?exists("select id from table where age = 1")--->exists (select id from table where age = 1)

notExists

notExists(String notExistsSql) notExists(boolean condition, String notExistsSql)

  • 拼接 NOT EXISTS ( sql語句 )
  • 例:?notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)

QueryWrapper

說明:

繼承自 AbstractWrapper ,自身的內部屬性 entity 也用于生成 where 條件

及 LambdaQueryWrapper, 可以通過 new QueryWrapper().lambda() 方法獲取

select

select(String... sqlSelect) select(Predicate<TableFieldInfo> predicate) select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)

  • 設置查詢字段

說明:

以上方法分為兩類.

第二類方法為:過濾查詢字段(主鍵除外),入參不包含 class 的調用前需要wrapper內的entity屬性有值! 這兩類方法重復調用以最后一次為準

  • 例:?select("id", "name", "age")
  • 例:?select(i -> i.getProperty().startsWith("test"))

UpdateWrapper

說明:

繼承自?AbstractWrapper?,自身的內部屬性?entity?也用于生成 where 條件

及?LambdaUpdateWrapper, 可以通過?new UpdateWrapper().lambda()?方法獲取!

set

set(String column, Object val) set(boolean condition, String column, Object val)

  • SQL SET 字段
  • 例:?set("name", "老李頭")
  • 例:?set("name", "")空字符串
  • 例:?set("name", null) null

setSql

setSql(String sql)

  • 設置 SET 部分 SQL
  • 例:?setSql("name = '老李頭'")

lambda

(這個lambda可以用方法引用,其他不行,支持鏈式編程)

  • 獲取?LambdaWrapper

在QueryWrapper是LambdaQueryWrapper

在UpdateWrapper是LambdaUpdateWrapper

樂觀OptimisticLockerInnerInterceptor

當要更新一條記錄的時候,希望這條記錄沒有被別人更新

樂觀鎖實現方式:

取出記錄時,獲取當前 version更新時,帶上這個 version執行更新時, set version = newVersion where version = oldVersion如果 version 不對,就更新失敗

spring boot 注解方式:

@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }

2.在實體類的字段上加上@Version注解

@Version private Integer version;

示例

// Spring Boot 方式 @Configuration @MapperScan("按需修改") public class MybatisPlusConfig { /** * 舊版 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } /** * 新版 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return mybatisPlusInterceptor; } }

代碼生成器

引入依賴

<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>最新版本</version> </dependency>

快速生成

FastAutoGenerator.create("url", "username", "password") .globalConfig(builder -> { builder.author("baomidou") // 設置作者 .enableSwagger() // 開啟 swagger 模式 .fileOverride() // 覆蓋已生成文件 .outputDir("D://"); // 指定輸出目錄 }) .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> { int typeCode = metaInfo.getJdbcType().TYPE_CODE; if (typeCode == Types.SMALLINT) { // 自定義類型轉換 return DbColumnType.INTEGER; } return typeRegistry.getColumnType(metaInfo); })) .packageConfig(builder -> { builder.parent("com.baomidou.mybatisplus.samples.generator") // 設置父包名 .moduleName("system") // 設置父包模塊名 .pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 設置mapperXml生成路徑 }) .strategyConfig(builder -> { builder.addInclude("t_simple") // 設置需要生成的表名 .addTablePrefix("t_", "c_"); // 設置過濾表前綴 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默認的是Velocity引擎模板 .execute();

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166735.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166735.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166735.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android開發從0開始(廣播)

應用廣播 發送標準廣播的三步驟 發送標準廣播&#xff1a; //發送標準廣播 Intent intent new Intent("com.dongnaoedu.chapter09.standard"); sendBroadcast(intent); 定義廣播接受者: public class StanderdReceiver extends BroadcastReceiver { public s…

在ASP.NET Core 中使用 .NET Aspire 消息傳遞組件

前言 云原生應用程序通常需要可擴展的消息傳遞解決方案&#xff0c;以提供消息隊列、主題和訂閱等功能。.NET Aspire 組件簡化了連接到各種消息傳遞提供程序&#xff08;例如 Azure 服務總線&#xff09;的過程。在本教程中&#xff0c;小編將為大家介紹如何創建一個 ASP.NET …

PLC通過RS232轉PROFINET與電子分析天平秤通訊案例

本案例是通過用興達易控的XD-PNR200型RS232轉Profinet網關連接電子分析天平秤與PLC通訊的配置案例&#xff0c;用到設備為西門子S7-1200PLC&#xff0c;RS232轉Profinet網關&#xff0c;電子分析天平秤。 打開博圖&#xff0c;添加PLC&#xff1b;本案例使用的是1200PLC。 添加…

『接口測試干貨』| Newman+Postman接口自動化測試完整過程

『接口測試干貨』| NewmanPostman接口自動化測試完整過程 1 Newman簡介2 如何安裝Newman&#xff1f;2.1 安裝NodeJs2.2 安裝Newman2.2 解決Newman不是內部命令 3 Newman使用3.1 Newman如何運行集合&#xff1f;3.2 如何查看幫助文檔&#xff1f;3.3 環境變量設置3.4 關于全局變…

微信小程序制作

如果你也想搭建一個小程序&#xff0c;但不知道如何入手&#xff0c;那么今天我就教你如何使用第三方制作平臺&#xff0c;在短短三十分鐘內搭建一個小程序。 一、登錄小程序制作平臺 首先&#xff0c;登錄到小程序制作平臺的官方網站或應用程序&#xff0c;進入后臺管理系統。…

【Oracle OCP考試】1z0-082(4)

1.Which two statements are true about the PMON background process? A. It rolls back transactions when a process fails&#xff08;當進程失敗時&#xff0c;它回滾事務&#xff09; B. It registers database services with all local and remote listeners known to…

文章解讀與仿真程序復現思路——電網技術 EI\CSCD\北大核心《考慮5G基站儲能可調度容量的有源配電網協同優化調度方法》

這篇文章的標題涉及到以下關鍵概念&#xff1a; 5G基站&#xff1a; 提到了5G基站&#xff0c;這表明文章的焦點可能是與第五代移動通信技術相關的內容。5G技術對于提高通信速度、降低延遲以及支持大規模連接等方面有顯著的改進&#xff0c;因此對于基站的電力需求和供應可能存…

2023年ESG投資研究報告

第一章 ESG投資概況 1.1 定義 ESG投資&#xff0c;亦稱負責任投資&#xff0c;是一種融合環境&#xff08;Environment&#xff09;、社會&#xff08;Social&#xff09;和治理&#xff08;Governance&#xff09;考量的投資方法&#xff0c;旨在通過綜合這些因素來優化投資…

美國汽車零部件巨頭 AutoZone 遭遇網絡攻擊

Security Affairs 網站披露&#xff0c;美國汽車配件零售商巨頭 AutoZone 稱其成為了 Clop MOVEit 文件傳輸網絡攻擊的受害者&#xff0c;導致大量數據泄露。 AutoZone 是美國最大的汽車零配件售后市場經銷商之一&#xff0c;在美國、墨西哥、波多黎各、巴西和美屬維爾京群島經…

算法-技巧-簡單-只出現一次的數字、多數元素

記錄一下算法題的學習10 只出現一次的數字 leetcode題目&#xff1a;給你一個 非空 整數數組 nums &#xff0c;除了某個元素只出現一次以外&#xff0c;其余每個元素均出現兩次。找出那個只出現了一次的元素。你必須設計并實現線性時間復雜度的算法來解決此問題&#xff0c;且…

「Whale 帷幄」連續入選科技榜單,AGI 沖擊波正在加速行業洗牌

以 AGI 為底座&#xff0c;品牌 MarTech 正在經歷一場前所未有的深度變革。 近日&#xff0c;彎弓研究院發布「中國 MarTech 500 強榜單」&#xff0c;以 2023 中國營銷技術&#xff08;MarTech&#xff09;生態為研究對象&#xff0c;洞察行業現象與未來趨勢。作為品牌數字化…

AMEYA360:蔡司新能源汽車解決方案驅動產業未來

電動化正在重塑中國汽車工業。自中國汽車工業開始發展以來&#xff0c;在電動化和智能化的浪潮推動下&#xff0c;汽車行業從未面臨著如此巨大的變革。得益于中國汽車產業尤其是新能源車過去十余年的激流勇進&#xff0c;消費者對新能源汽車的接受度也在發生轉變。新能源汽車市…

2016年全國碩士研究生入學統一考試管理類專業學位聯考英語(二)試題

Section IUse of English Directions: Read the following text.Choose the best word(s) for each numbered blank and mark A&#xff0c;B,Cor D on the ANSWER SHEET.(10 points)   Happy people work differently.They’re more productive&#xff0c;more creative&am…

前后端性能優化實踐(含Java代碼部分、數據庫部分、React前端部分)

最近的一個大屏報表統計的接口查詢速度很慢&#xff0c;耗時近一分鐘左右&#xff0c;數據量級只是700萬左右&#xff0c;但很慢&#xff0c;最后優化到4秒左右&#xff0c;客戶還能接受&#xff0c;但其實還可以在優化&#xff0c;先這樣吧&#xff0c;簡單記錄下。這次主要優…

App Inventor 2 文本轉數字

App Inventor 2 是弱語言類型&#xff0c;文本和數字之間不用刻意去轉換&#xff0c;之間賦值就可以了。文本賦值給數字變量如下&#xff1a; 運行結果&#xff1a;124 注意&#xff1a;數字變量初始化的時候要給一個數字的初始值&#xff0c;表明它是數字。 如果文本中含有非…

java與c++中的分支語句switch的不同

java中的switch后可用字符串,而C只能用字符和數字 switch(suffix){case "js":contentType"text/javascript";break;case "css":contentType"text/css";break;}c switch (x){case 0:case 1:case 2:rth 3;break;case 3:case 4:case 5:r…

系列三、事務

一、事務 1.1、概述 事務是數據庫操作的基本單元&#xff0c;它是指邏輯上的一組操作&#xff0c;要么都成功&#xff0c;要么都失敗。典型場景&#xff1a;轉賬&#xff0c;例如Jack給Rose轉賬1000元&#xff0c;轉賬成功&#xff1a;Jack賬戶的余額少1000元&#xff0c;Rose…

關于進制的轉化

二進制轉十進制&#xff1a; &#x1f530; 方法一&#xff1a;二進制轉十進制&#xff0c;用各數的碼位與位權的乘積之和&#xff0c;說白了就是用從右到左的每個數去乘以2的冪次方&#xff08;最右邊是0&#xff09;&#xff0c;然后就所有的數相加。 補充&#xff1a;位權是…

<藍橋杯軟件賽>零基礎備賽20周--第7周--棧和二叉樹

報名明年4月藍橋杯軟件賽的同學們&#xff0c;如果你是大一零基礎&#xff0c;目前懵懂中&#xff0c;不知該怎么辦&#xff0c;可以看看本博客系列&#xff1a;備賽20周合集 20周的完整安排請點擊&#xff1a;20周計劃 每周發1個博客&#xff0c;共20周&#xff08;讀者可以按…

VMware共享文件夾不能放mysql的數據

概要 使用VMware搭建了一個虛擬機&#xff0c;準備做數據庫服務器。服務器是linux系統&#xff0c;安裝了mysql和redis。為了數據安全&#xff0c;準備將mysql的數據文件放到共享文件夾中&#xff0c;嘗試多次后都沒成功。問題可能是共享文件夾中的文件的擁有者都是root&#…