治理有精度,AI賦智加強城市精細化管理
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) { |
---|
列舉類,用於選擇對應的查詢條件。