Mybatis-plus學習筆記,基於springboot
阿新 • • 發佈:2020-08-28
1、依賴
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.2</version> </dependency>
2、自動生成程式碼
public class CodeBuilder { public static void main(String[] args) { AutoGenerator autoGenerator = new AutoGenerator(); // 資料庫表名 String[] tableList = { "" }; // 作者 String author = ""; // 資料庫樂觀鎖欄位名 String version = "version"; // 資料庫邏輯刪除欄位名 String deleted = "deleted"; // 資料庫表字首 String tablePrefix = ""; // 欄位字首 String columnPrefix = ""; // 包名 String packageName = ""; // JDBC String dataBaseUrl = ""; String dataBaseDriverName = ""; String dataBaseUsername = ""; String dataBasePassword = ""; // 自動填充配置 // 根據自己的表結構修改 // 建立時間 TableFill createTime = new TableFill("f_create_time", FieldFill.INSERT); // 修改時間 TableFill updateTime = new TableFill("f_update_time", FieldFill.INSERT_UPDATE); // 經辦人ID TableFill operatorId = new TableFill("f_operator_id", FieldFill.INSERT_UPDATE); // 經辦人名字 TableFill operator = new TableFill("f_operator", FieldFill.INSERT_UPDATE); ArrayList<TableFill> list = new ArrayList<>(); list.add(createTime); list.add(updateTime); list.add(operatorId); list.add(operator); // 全域性配置 GlobalConfig globalConfig = new GlobalConfig(); String path = System.getProperty("user.dir"); globalConfig.setOutputDir(path + "/src/main/java"); globalConfig.setAuthor(author); globalConfig.setOpen(false); globalConfig.setServiceName("%sService"); globalConfig.setControllerName("%sController"); globalConfig.setEntityName("%sPO"); globalConfig.setMapperName("%sDao"); globalConfig.setFileOverride(true); globalConfig.setBaseResultMap(true); globalConfig.setBaseColumnList(true); globalConfig.setActiveRecord(true); globalConfig.setSwagger2(true); globalConfig.setIdType(IdType.AUTO); globalConfig.setDateType(DateType.ONLY_DATE); autoGenerator.setGlobalConfig(globalConfig); // 資料來源配置 DataSourceConfig dataSourceConfig = new DataSourceConfig(); dataSourceConfig.setUrl(dataBaseUrl); dataSourceConfig.setDbType(DbType.MYSQL); dataSourceConfig.setDriverName(dataBaseDriverName); dataSourceConfig.setUsername(dataBaseUsername); dataSourceConfig.setPassword(dataBasePassword); autoGenerator.setDataSource(dataSourceConfig); // 包配置 PackageConfig packageConfig = new PackageConfig(); packageConfig.setMapper("dao"); packageConfig.setController("controller"); packageConfig.setEntity("entity.po"); packageConfig.setService("service"); packageConfig.setParent(packageName); autoGenerator.setPackageInfo(packageConfig); // 策略設定 StrategyConfig strategy = new StrategyConfig(); strategy.setInclude(tableList); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setControllerMappingHyphenStyle(true); strategy.setEntitySerialVersionUID(false); strategy.setEntityTableFieldAnnotationEnable(true); strategy.setVersionFieldName(version); strategy.setLogicDeleteFieldName(deleted); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityColumnConstant(true); strategy.setChainModel(true); strategy.setTablePrefix(tablePrefix); strategy.setFieldPrefix(columnPrefix); strategy.setTableFillList(list); // RestFull 風格 strategy.setRestControllerStyle(true); strategy.setControllerMappingHyphenStyle(true); autoGenerator.setStrategy(strategy); autoGenerator.execute(); } }
3、springboot註解新增mapperscan
@MapperScan("com.hong.mapper")//可以寫在MybatisplusConfig中
4、註解
@TableName
-
表名註解
屬性 型別 必須指定 預設值 描述 value String 否 "" 表名 schema String 否 "" schema keepGlobalPrefix boolean 否 false 是否保持使用全域性的 tablePrefix 的值(如果設定了全域性 tablePrefix 且自行設定了 value 的值) resultMap String 否 "" xml 中 resultMap 的 id autoResultMap boolean 否 false 是否自動構建 resultMap 並使用(如果設定 resultMap 則不會進行 resultMap 的自動構建並注入)
@TableId
-
主鍵註解
屬性 型別 必須指定 預設值 描述 value String 否 "" 主鍵欄位名 type Enum 否 IdType.NONE 主鍵型別 -
IdType
值 描述 AUTO 資料庫ID自增 NONE 無狀態,該型別為未設定主鍵型別(註解裡等於跟隨全域性,全局裡約等於 INPUT) INPUT insert前自行set主鍵值 ASSIGN_ID 分配ID(主鍵型別為Number(Long和Integer)或String)(since 3.3.0),使用介面 IdentifierGenerator
的方法nextId
(預設實現類為DefaultIdentifierGenerator
雪花演算法)
@TableField
-
欄位註解
屬性 型別 必須指定 預設值 描述 value String 否 "" 資料庫欄位名 el String 否 "" 對映為原生 #{ ... }
邏輯,相當於寫在 xml 裡的#{ ... }
部分exist boolean 否 true 是否為資料庫表字段 condition String 否 "" 欄位 where
實體查詢比較條件,有值設定則按設定的值為準,沒有則為預設全域性的%s=#{%s}
,參考update String 否 "" 欄位 update set
部分注入, 例如:update="%s+1":表示更新時會set version=version+1(該屬性優先順序高於el
屬性)insertStrategy Enum N DEFAULT 舉例:NOT_NULL: insert into table_a(column) values (#{columnProperty})
updateStrategy Enum N DEFAULT 舉例:IGNORED: update table_a set column=#{columnProperty}
whereStrategy Enum N DEFAULT 舉例:NOT_EMPTY: where column=#{columnProperty}
fill Enum 否 FieldFill.DEFAULT 欄位自動填充策略 select boolean 否 true 是否進行 select 查詢 keepGlobalFormat boolean 否 false 是否保持使用全域性的 format 進行處理 jdbcType JdbcType 否 JdbcType.UNDEFINED JDBC型別 (該預設值不代表會按照該值生效) typeHandler Class<? extends TypeHandler> 否 UnknownTypeHandler.class 型別處理器 (該預設值不代表會按照該值生效) numericScale String 否 "" 指定小數點後保留的位數
@Version
- 樂觀鎖
@TableLogic
-
邏輯刪除註解
屬性 型別 必須指定 預設值 描述 value String 否 "" 邏輯未刪除值 delval String 否 "" 邏輯刪除值
5、配置外掛
1、日誌(控制檯輸出)
#配置日誌輸出
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2、自動填充策略
-
資料庫新增對應欄位
-
create_time
-
update_time
-
datatime 型別
-
-
對應屬性需要加上註解
@TableField(fill = FieldFill.INSERT) private Date creatTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
-
編寫MybatisPlusConfig類
@Configuration public class MybatisPlusConfig { /** * 註冊欄位自動填充 * * @return */ @Bean public MetaObjectHandler getMetaObjectHandler() { return new MetaObjectHandler() { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime", new Date(), metaObject); } }; } /** * 樂觀鎖外掛 * * @return */ @Bean public OptimisticLockerInterceptor getOptimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } /** * 分頁外掛 * * @return */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
3、樂觀鎖version
-
資料庫新增對應欄位,預設值為1
- version
-
實體類新增對應註解
@Version private Integer version;
4、邏輯刪除
-
解釋:在邏輯上實現刪除,實際上資料庫沒有被刪除,但是普通使用者查詢不到,只有管理員能查詢
-
在資料庫新增對應欄位,預設0為沒有刪除,1為邏輯刪除
- deleted
-
實體類中新增對應註解
@TableLogic private Integer deleted;
5、分頁
-
查詢測試
@Test void selectPageTest() { //引數一:當前頁 //引數二:頁面大小 Page<TUser> objectPage = new Page<>(1,2); tUserMapper.selectPage(objectPage,null); objectPage.getRecords().forEach(System.out::println); }
6、效能分析外掛(P6spy)
-
匯入依賴
<dependency> <groupId>p6spy</groupId> <artifactId>p6spy</artifactId> <version>3.9.0</version> </dependency>
-
接著編輯 application.properties 檔案,更換資料庫連線驅動:
#資料庫資訊配置 spring.datasource.username= spring.datasource.password= spring.datasource.url=jdbc:p6spy:mysql: spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
-
最後建立 spy.properties 配置檔案即可
#3.2.1以上使用 modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory # 自定義日誌列印 logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger #日誌輸出到控制檯 appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger # 使用日誌系統記錄 sql #appender=com.p6spy.engine.spy.appender.Slf4JLogger # 設定 p6spy driver 代理 deregisterdrivers=true # 取消JDBC URL字首 useprefix=true # 配置記錄 Log 例外,可去掉的結果集有error,info,batch,debug,statement,commit,rollback,result,resultset. excludecategories=info,debug,result,commit,resultset # 日期格式 dateformat=yyyy-MM-dd HH:mm:ss # 實際驅動可多個 #driverlist=org.h2.Driver # 是否開啟慢SQL記錄 outagedetection=true # 慢SQL記錄標準 2 秒 outagedetectioninterval=2
7、多資料來源
- 匯入依賴
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
- 資料來源配置檔案
spring:
datasource:
dynamic:
primary: master #設定預設的資料來源或者資料來源組,預設值即為master
strict: false #設定嚴格模式,預設false不啟動. 啟動後在未匹配到指定資料來源時候會丟擲異常,不啟動則使用預設資料來源.
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0開始支援SPI可省略此配置
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_2:
url: ENC(xxxxx) # 內建加密,使用請檢視詳細文件
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
schema: db/schema.sql # 配置則生效,自動初始化表結構
data: db/data.sql # 配置則生效,自動初始化資料
continue-on-error: true # 預設true,初始化失敗是否繼續
separator: ";" # sql預設分號分隔符
#......省略
#以上會配置一個預設庫master,一個組slave下有兩個子庫slave_1,slave_2
- 使用@DS註解切換資料來源
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("slave_1")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
6、CRUD(service層)
save
// 插入一條記錄(選擇欄位,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(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);
update
// 根據 UpdateWrapper 條件,更新記錄 需要設定sqlset
boolean update(Wrapper<T> updateWrapper);
// 根據 whereEntity 條件,更新記錄
boolean update(T entity, Wrapper<T> updateWrapper);
// 根據 ID 選擇修改
boolean updateById(T entity);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> 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);