1.簡介
1.什么是Mybatis-plus?
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。
2.開發環境准備
1.配置數據庫環境,創建一張測試表
2.創建springboot項目,引入依賴
<!--mybatis plus 起步依賴--> |
---|
3.編寫DataSource相關配置
spring: |
---|
4.編寫實體類
@Data |
---|
1) @TableField("name") 指定映射關系。
- 實體類的屬性名和數據庫的字段名自動映射。
- 自動映射條件:名稱一樣,或者數據庫字段使用_分割,實體類屬性名使用駝峰名稱
- 否則需要使用@TableField("name") 指定映射關系。
2)@TableField(exist = false) 忽略某個字段的查詢和插入。
3) @TableId(type = IdType.AUTO)設置id生成策略:AUTO 數據庫自增。
- AUTO 數據庫ID自增,依賴於數據庫。在插入操作生成SQL語句時,不會插入主鍵這一列
- NONE 未設置主鍵類型。用戶輸入,為空則會根據主鍵的全局策略自動生成
- INPUT 需要手動設置主鍵,若不設置。插入操作生成SQL語句時,主鍵這一列的值會是
null
- ID_WORKER(Long) 當實體類的主鍵屬性為空時,才會自動填充
- ID_WORKER_STR(String) 當實體類的主鍵屬性為空時,才會自動填充
- UUID 當實體類的主鍵屬性為空時,才會自動填充,使用UUID
4)@TableLogic(value = "0", delval = "1")設置邏輯刪除字段,並設置刪除與未刪的代表值
添加該注解之后:
- 刪除轉變為更新,調用mp提供的刪除接口時,更新disable字段0->1
- 只對自動注入的SQL起效
- 查詢時自動生成where disable=0查詢
- 更新時自動生成where disable=0條件防止更新到已刪除數據
- 自己寫的刪除接口依然為物理刪除
不添加此注解時:
- mp提供的刪除接口默認為物理刪除
5.啟動類增加 @MapperScan 注解,指定dao包的位置
@SpringBootApplication |
---|
3.Mapper 接口
編寫dao
使用mp定義Mapper,需要讓Mapper接口繼承 BaseMapper接口。
@Mapper |
---|
1.增加
// 插入一條記錄
int insert(T entity);
類型 |
參數名 |
描述 |
---|---|---|
T | entity | 實體對象 |
2.刪除
// 根據 entity 條件,刪除記錄
int delete(Wrapper<T> wrapper);
// 刪除(根據ID 批量刪除)
int deleteBatchIds(Collection<? extends Serializable> idList);
// 根據 ID 刪除
int deleteById(Serializable id);
// 根據 columnMap 條件,刪除記錄
int deleteByMap(Map<String, Object> columnMap);
類型 | 參數名 | 描述 |
---|---|---|
Wrapper<T> | wrapper | 實體對象封裝操作類(可以為 null) |
Collection<? extends Serializable> | idList | 主鍵ID列表(不能為 null 以及 empty) |
Serializable | id | 主鍵ID |
Map<String, Object> | columnMap | 表字段 map 對象 |
3.修改
// 根據 whereWrapper 條件,更新記錄
int update(Wrapper<T> updateWrapper);
// 根據 ID 修改
int updateById(T entity);
類型 | 參數名 | 描述 |
---|---|---|
T | entity | 實體對象 (set 條件值,可為 null) |
Wrapper<T> | updateWrapper | 實體對象封裝操作類(可以為 null,里面的 entity 用於生成 where 語句) |
4.查詢
// 根據 ID 查詢
T selectById(Serializable id);
// 根據 entity 條件,查詢一條記錄
T selectOne(Wrapper<T> queryWrapper);
// 查詢(根據ID 批量查詢)
List<T> selectBatchIds(Collection<? extends Serializable> idList);
// 根據 entity 條件,查詢全部記錄
List<T> selectList(Wrapper<T> queryWrapper);
// 查詢(根據 columnMap 條件)
List<T> selectByMap(Map<String, Object> columnMap);
// 根據 Wrapper 條件,查詢全部記錄,只展示查詢的字段,不展示為null的字段
List<Map<String, Object>> selectMaps(Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄。注意: 只返回第一個字段的值
List<Object> selectObjs(Wrapper<T> queryWrapper);
// 根據 entity 條件,查詢全部記錄(並翻頁)
IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄(並翻頁)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢總記錄數
Integer selectCount(Wrapper<T> queryWrapper);
類型 | 參數名 | 描述 |
---|---|---|
Serializable | id | 主鍵ID |
Wrapper<T> | queryWrapper | 實體對象封裝操作類(可以為 null) |
Collection<? extends Serializable> | idList | 主鍵ID列表(不能為 null 以及 empty) |
Map<String, Object> | columnMap | 表字段 map 對象 |
IPage<T> | page | 分頁查詢條件(可以為 RowBounds.DEFAULT) |
條件構造器
AbstractWrapper是QueryWrapper和 UpdateWrapper的父類,用於生成 sql 的 where 條件
AbstractWrapper:
|
---|
-
LIKE '%值%'
- 例: like("name", "王")--->name like '%王%
|
---|
-
等於 =
-
例: eq("name", "老王")--->name = '老王'
|
---|
-
LIKE '%值'
-
例: likeLeft("name", "王")--->name like '%王'
|
---|
- LIKE '值%'
- 例: likeRight("name", "王")--->name like '王%'
|
---|
- 大於 >
- 例: gt("age", 18)--->age > 18
|
---|
-
大於等於 >=
-
例: ge("age", 18)--->age >= 18
|
---|
- 小於 <
- 例: lt("age", 18)--->age < 18
|
---|
- 小於等於 <=
- 例: le("age", 18)--->age <= 18
|
---|
- 字段 IS NULL
- 例: isNull("name")--->name is null
|
---|
- 字段 IS NOT NULL
- 例: isNotNull("name")--->name is not null
|
---|
- 字段 IN (value.get(0), value.get(1), ...)
- 例: in("age",{1,2,3})--->age in (1,2,3)
|
---|
- 排序:ORDER BY 字段, ...
- 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC
|
---|
- BETWEEN 值1 AND 值2
- 例: between("age", 18, 30)--->age between 18 and 30
|
---|
- NOT BETWEEN 值1 AND 值2
- 例: notBetween("age", 18, 30)--->age not between 18 and 30
|
---|
- 分組:GROUP BY 字段, ...
- 例: groupBy("id", "name")--->group by id,name
|
---|
- HAVING ( sql語句 )
- 例: having("sum(age) > 10")--->having sum(age) > 10
- 例: having("sum(age) > {0}", 11)--->having sum(age) > 11
|
---|
- 拼接 OR
- 主動調用or表示緊接着下一個方法不是用and連接!(不調用or則默認為使用and連接)
|
---|
- 該方法可用於數據庫函數 動態入參的params對應前面的{index}部分.這樣是不會有sql注入風險的,反之會有!
-
apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
QueryWrapper:
|
---|
- 設置查詢字段
- 例: select("id", "name", "age")->select id,name,age
UpdateWrapper:
|
---|
- SQL SET 字段
- 例: set("name", "wang")
- 例: set("name", "")--->數據庫字段值變為空字符串
- 例: set("name", null)--->數據庫字段值變為null
|
---|
- 設置 SET 部分 SQL
- 例: setSql("name = 'wang'")
4.Service接口
說明:
通用 Service CRUD 封裝IService 接口,進一步封裝 CRUD 采用 get 查詢、單行 remove 刪除、 list 查詢集合、 page 分頁, 前綴命名方式區分 Mapper 層避免混淆。
需要繼承Service類
public interface UserInfoService extends IService<UserInfo> {} |
---|
建議如果存在自定義通用 Service 方法,請創建自己的 BaseService 繼承 Mybatis-Plus 提供的基類
public interface UserInfoService extends BaseService<UserInfo> {} public interface BaseService extends IService<UserInfo> {} |
---|
接口介紹:
#Save
// 插入一條記錄(選擇字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
類型 |
參數名 |
描述 |
---|---|---|
T | entity | 實體對象 |
Collection<T> | entityList | 實體對象集合 |
SaveOrUpdate
// 主鍵id存在更新記錄,否則插入一條記錄
boolean saveOrUpdate(T entity);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
類型 | 參數名 | 描述 |
---|---|---|
T | entity | 實體對象 |
Collection<T> | entityList | 實體對象集合 |
int | batchSize | 插入批次數量 |
#Remove
// 根據 entity 條件,刪除記錄
boolean remove(Wrapper<T> queryWrapper);
// 根據 ID 刪除
boolean removeById(Serializable id);
// 根據 columnMap 條件,刪除記錄
boolean removeByMap(Map<String, Object> columnMap);
// 刪除(根據ID 批量刪除)
boolean removeByIds(Collection<? extends Serializable> idList);
類型 | 參數名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 實體包裝類 QueryWrapper |
Serializable | id | 主鍵ID |
Map<String, Object> | columnMap | 表字段 map 對象 |
Collection<? extends Serializable> | idList | 主鍵ID列表 |
#Update
// 根據 updateWrapper條件,更新記錄
boolean update(T updateEntity, Wrapper<T> updateWrapper);
// 根據 ID 選擇修改
boolean updateById(T entity);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
類型 | 參數名 | 描述 |
---|---|---|
Wrapper<T> | updateWrapper | 實體對象封裝操作類 UpdateWrapper |
T | entity | 實體對象 |
Collection<T> | entityList | 實體對象集合 |
int | batchSize | 更新批次數量 |
#Get
// 根據 ID 查詢
T getById(Serializable id);
// 根據 Wrapper,查詢一條記錄。結果集,如果是多個會拋出異常
T getOne(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據 Wrapper,查詢一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);
類型 | 參數名 | 描述 |
---|---|---|
Serializable | id | 主鍵ID |
Wrapper<T> | queryWrapper | 實體對象封裝操作類 QueryWrapper |
boolean | throwEx | 有多個 result 是否拋出異常 |
T | entity | 實體對象 |
#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);
// 查詢所有列表,不顯示為null的字段
List<Map<String, Object>> listMaps();
// 根據條件查詢所有列表,不顯示為null的字段
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查詢全部記錄,只顯示第一個字段
List<Object> listObjs();
// 根據 Wrapper 條件,查詢全部記錄
List<Object> listObjs(Wrapper<T> queryWrapper);
類型 | 參數名 | 描述 |
---|---|---|
Wrapper<T> | queryWrapper | 實體對象封裝操作類 QueryWrapper |
Collection<? extends Serializable> | idList | 主鍵ID列表 |
Map<?String, Object> | columnMap | 表字段 map 對象 |
#Count
// 查詢總記錄數
int count();
// 根據 Wrapper 條件,查詢總記錄數
int count(Wrapper<T> queryWrapper);
類型 |
參數名 |
描述 |
---|---|---|
Wrapper<T> | queryWrapper | 實體對象封裝操作類 QueryWrapper |
5.分頁插件
寫mybatis-plus配置類,用來配置使用的數據庫
@Configuration |
---|
寫service,可以調用mp中service層提供的分頁接口和Ipage插件進行分頁。
// 無條件分頁查詢
IPage<T> page(IPage<T> page);
// 條件分頁查詢
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 無條件分頁查詢,不顯示null字段
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 條件分頁查詢,不顯示null字段
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
類型 | 參數名 | 描述 |
---|---|---|
IPage<T> | page | 翻頁對象 |
Wrapper<T> | queryWrapper | 實體對象封裝操作類 QueryWrapper |
編碼:
@Override |
---|
測試
所執行的sql
6.SQL分析
在MybatisPlusConfig當中添加配置代碼,此配置可以顯示SQ語句和運行時間
@Bean |
---|
測試
7.代碼生成器
1.添加依賴
|
---|
2.添加模板依賴
MyBatis-Plus 支持 Velocity(默認)、Freemarker、Beetl,項目中使用的是Freemarker,我們以Freemarker為例。
<dependency> |
---|
3.編寫配置類
設置存放路徑,作者
GlobalConfig gc = new GlobalConfig(); |
---|
數據源配置
DataSourceConfig dsc = new DataSourceConfig(); |
---|
包配置
PackageConfig pc = new PackageConfig(); |
---|
其他配置
// 如果模板引擎是 freemarker |
---|
7.測試
執行main方法,輸入模塊名和表名:
成功生成代碼
8.Demo
9.fir項目
1.fir-db
1.實體類添加注解,以MetricData為例,用於數據庫表與實體類、字段與屬性對應
@TableName("metric_data") |
---|
2.Mapper層繼承BaseMapper,可以調用mp提供的API
public interface MetricDataRepository extends BaseRepository<MetricData, Long>{} public interface BaseRepository<T, ID extends Serializable> extends BaseMapper<T>() |
---|
3.Service層繼承Iservice,可以調用mp提供的API
public interface MetricDataService extends BaseService<MetricData>{} public interface BaseService<T> extends IService<T>{} |
---|
4.使用了自定義通用Service類,定義了一些常用的方法,方便復用
public interface BaseService<T> extends IService<T> |
---|
5.MybatisPlusConfig中寫了一些配置,用於配置分頁插件和SQL分析插件
@Configuration |
---|
6.條件查詢的構造方式
Controller層,attribute(字段)、operator(操作)、values(值)封裝到Condition中,col(字段)、direction(方向)封裝到Ordering中,然后把這些數據封裝到SearchRequest中。
Service層,調用BaseService中的findBySearchRequest方法進行分頁查詢,迭代構造條件,最后返回SearchResult。
例:Controller層:封裝Condition、Ordering、page、limit到SearchRequest,以searchRequest為參數調用service中的search()。
這里面封裝數據的SearchRequest,代碼如下圖所示。
Service層:調用BaseService類中的findBySearchRequest方法用於分頁查詢。
返回結果SearchResult,代碼如圖所示。
BaseService中findBySearchRequest方法,主要用於分頁,調用contructWrapper方法構造條件。
BaseService中contructWrapper方法用於迭代構造查詢條件,調用addCondition方法。
addCondition方法:主要用於匹配操作名稱和構造條件。
private QueryWrapper addCondition(String attribute, String operator, List<Object> valuesList, QueryWrapper queryWrapper) { |
---|
枚舉類,用於選擇對應的查詢條件。