【Java萌新】MyBatis-Plus案例
MyBatis-Plus是什么?
https://baomidou.com/#/
Mybatis-Plus(簡稱MP)是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。這是官方給的定義,關于mybatis-plus的更多介紹及特性,可以參考mybatis-plus官網。那么它是怎么增強的呢?其實就是它已經封裝好了一些crud方法,我們不需要再寫xml了,直接調用這些方法就行,就類似于JPA。
特性
- 無侵入 :只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
- 損耗小 :啟動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作, BaseMapper
- 強大的 CRUD 操作 :內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求, 以后的簡單的增刪改查, 它不用自己寫了!
- 支持 Lambda 形式調用 :通過 Lambda 表達式,方便的編寫各類查詢條件,無需再擔心字段寫錯
- 支持主鍵自動生成 :支持多達 4 種主鍵策略(內含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
- 支持 ActiveRecord 模式 :支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作
- 支持自定義全局通用操作 :支持全局通用方法注入( Write once, use anywhere )
- 內置代碼生成器 :采用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用,可插拔的方式(自動幫你生成代碼)
- 內置分頁插件 :基于 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之后,寫分頁等同于普通 List 查詢
- 分頁插件支持多種數據庫 :支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種數據庫
- 內置性能分析插件 :可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢
- 內置全局攔截插件 :提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
快速入門
地址: https://baomidou.com/guide/quick-start.html
使用第三方組件
- 導入對應依賴
- 研究如何讓編寫配置
- 代碼如何編寫
- 提高拓展
步驟
創建數據庫
mybatis_plus
創建 user表
DROP TABLE IF EXISTS user;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) );真實開發過程中, version(樂觀鎖)、delete(邏輯刪除)、gmt_create、gm_modified其對應的數據庫 Data 腳本如下:
DELETE FROM user;INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com');創建SpringBoot項目
mybatis_plus
導入依賴
<!--數據庫驅動--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--mybatis-plus-boot-starter是自己開發的, 并非官方--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.0.5</version></dependency>說明: 我們使用mybatis-plus可以節省我們大量代碼, 盡量不要導入mybtis和mybatis-plus! 版本差異
連接數據庫
spring.datasource.username=root spring.datasource.data-password=123456 spring.datasource.url=jdbc:mysql://cdb-q9atzwrq.bj.tencentcdb.com:10167/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # serverTimezone=GMT 時區 8.0以上版本需要添加否則會報錯傳統項目結構對比使用mybatis-plus之后
- pojo-dao(連接mybatis, 配置mapper.xml文件)service-controller
- 使用mybatis-plus之后
- pojo
- mapper接口
- 使用
思考問題
- SQL誰幫我們寫好了? MyBatis-Plus都寫好了
方法哪里來? MyBatis-Plus都寫好了
配置日志
我們所有的SQL是不可見的, 我們希望知道它是怎么執行的, 所以我們必須要看日志
(真正上線, 在下)
CRUD拓展
Insert
@Testvoid testInsert() {User user = new User();user.setName("掌上編程");user.setAge(19);user.setEmail("2460798168@qq.com");userMapper.insert(user);}數據庫插入的id的默認值為:全局的唯一id
主鍵的策略
分布式系統唯一id生成:
默認@TableId(type = IdType.ID_WORKER)private Long id;雪花算法:snowflake是Twitter開源的分布式ID生成算法,結果是一個long型的ID。其核心思想是:使用41bit作為毫秒數,10bit作為機器的ID(5個bit是數據中心,5個bit的機器ID),12bit作為毫秒內的流水號(意味著每個節點在每毫秒可以產生 4096 個 ID),最后還有一個符號位,永遠是0。具體實現的代碼可以參看https://github.com/twitter/snowflake。
主鍵自增
我們需要配置主鍵自增
-
實體類字段上 @TableId(type = IdType.AUTO)
-
數據庫字段一定要自增!
-
再次測試插入即可
其他源碼檢測
public enum IdType {AUTO(0), //數據庫id自增NONE(1), //未設置主鍵INPUT(2), //手動輸入ID_WORKER(3),//默認的全局idUUID(4), //全局唯一id uuidID_WORKER_STR(5); //ID_WORKER 字符串表示法private int key;private IdType(int key) {this.key = key;}public int getKey() {return this.key;} }更新操作
@Testvoid testUpdate() {User user = new User();//通過條件自動拼接動態sqluser.setId(1L);user.setEmail("21211@qq.com");int i = userMapper.updateById(user);System.out.println(i);}自動填充
創建時間、更改時間! 這些操作一遍都是自動化完成的, 我們不希望手動更新!
阿里巴巴開發手冊:所有的數據表:gm_create、 gmt_modified 幾乎所有的表都需要配置上!而且需要自動化!
方式一 數據庫級別
- 在表中新增字段create_time、 update_time
方式二:代碼級別
數據庫的時間默認值去掉
直接在實體類中
package cn.com.codingce.pojo;import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.Date;/*** @author xzMa*/ @Data @AllArgsConstructor @NoArgsConstructor public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;@TableField(fill = FieldFill.INSERT)private Date createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private Date updateTime;}MyMetaObjectHandler
package cn.com.codingce.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component;import java.util.Date;/*** 自己寫的處理器* @author xzMa*/ @Slf4j @Component //一定不要把我們的處理器加到IOC中 public class MyMetaObjectHandler implements MetaObjectHandler {//插入時的填充策略@Overridepublic void insertFill(MetaObject metaObject) {log.info("Start insert fill ...");//String fieldName, Object fieldVal, MetaObject metaObjectthis.setFieldValByName("createTime", new Date(), metaObject);this.setFieldValByName("updateTime", new Date(), metaObject);}//更新時的填充策略@Overridepublic void updateFill(MetaObject metaObject) {log.info("Start update fill ...");this.setFieldValByName("updateTime", new Date(), metaObject);} }樂觀鎖
在面試過程中, 我們經常會被問到的樂觀鎖, 悲觀鎖! 這個其實非常簡單!
樂觀鎖:樂觀鎖( Optimistic Locking ) 相對悲觀鎖而言,樂觀鎖假設認為數據一般情況下不會造成沖突,所以在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。
故名思意十分樂觀, 它總是認為不會出現問題, 無論干什么都不去上鎖! 如果出現問題, 再次更新新值測試(version new version)
悲觀鎖:故名思意十分悲觀, 它總認為總是出現問題, 無論干什么都會上鎖! 再去操作!
樂觀鎖機制:
- 取出記錄記錄, 獲取當前version
- 更新時, 帶上這個version
- 執行更新時, set version = new Version where version = oldVersion
- 如果version不對, 就更新失敗
測試MP樂觀鎖插件
- 給數據庫中添加version字段
- 我們對實體類添加對應的字段
- 注冊組件
- 測試
查詢操作
@Testpublic void select() {User user = userMapper.selectById(1L);System.out.println(user);}@Testpublic void selectBatchIds() {List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));users.forEach(System.out::println);}//條件查詢 map@Testpublic void testSelectByBathIds() {HashMap<String, Object> map = new HashMap<>();//自定義要查詢map.put("name", "xzMhehe222");map.put("age", 12);List<User> userList = userMapper.selectByMap(map);userList.forEach(System.out::println);}分頁查詢
分頁在網站使用的十分之多
- 原始的limit進行分頁
- pageHelper第三方插件
- MP其實也內置了分頁插件
如何使用
配置攔截器組件
//Spring boot方式 @Configuration @MapperScan("com.baomidou.cloud.service.*.mapper*") public class MybatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();} }- 直接使用Page插件即可
基本刪除操作
//真刪@Testpublic void testDelete() {userMapper.deleteById(1L);}//批量刪除@Testpublic void testDeleteBatchId() {userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L));}//通過map刪除@Testpublic void testDeleteMap() {HashMap<String, Object> map = new HashMap<>();map.put("name", "xzMhehe");userMapper.deleteByMap(map);}我們在工作中會遇到一些問題:邏輯刪除
邏輯刪除
物理刪除:從數據庫中直接刪除
邏輯刪除:在數據庫中沒有移除,而是通過一個變量讓他失效! deleted = 0 =>deleted = 1
管理員可以查看刪除記錄!防止數據丟失,類似于回收站
- 在數據庫中添加deleted字段
- 在實體類中添加屬性
- 配置
性能分析插件
在平時開發中, 會遇到一些慢sql. 測試!druid
MP也提供性能分析插件, 如果超過這個時間停止運行!
- 導入插件
- 測試使用
條件構造器
十分重要 Wrapper
- 測試1
- 測試2
代碼自動生成器
dao pojo service controller 都是自動生成
package cn.com.codingce.generator;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.po.TableFill; import com.baomidou.mybatisplus.generator.config.rules.DateType; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;import java.util.ArrayList;public class CodeGenerator {public static void main(String[] args) {// 1、創建代碼生成器AutoGenerator mpg = new AutoGenerator();// 2、全局配置GlobalConfig gc = new GlobalConfig();//當前的項目路徑String projectPath = System.getProperty("user.dir");//所有代碼都會生成到 /src/main/java 路徑下gc.setOutputDir(projectPath + "/src/main/java");gc.setAuthor("小馬Coding");gc.setOpen(false); //生成后是否打開資源管理器gc.setFileOverride(false); //重新生成時文件是否覆蓋gc.setServiceName("%sService"); //去掉Service接口的首字母Igc.setIdType(IdType.ID_WORKER_STR); //主鍵策略gc.setDateType(DateType.ONLY_DATE);//定義生成的實體類中日期類型gc.setSwagger2(true);//開啟Swagger2模式mpg.setGlobalConfig(gc);// 3、數據源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://cdb-q9atzwrq.bj.tencentcdb.com:10167/codingstudy?useUnicode=true&characterEncoding=utf-8&useSSL=false");dsc.setDriverName("com.mysql.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("123456");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setModuleName("blog");pc.setParent("cn.com.codingce");pc.setController("controller");pc.setEntity("pojo");pc.setService("service");pc.setMapper("mapper");mpg.setPackageInfo(pc);// 5、策略配置StrategyConfig strategy = new StrategyConfig();//strategy.setInclude("ze_user");//設置要映射的表名//strategy.setInclude("ze_user", "ze_course");//可設置多個strategy.setInclude("ze_user");//設置要映射的表名strategy.setNaming(NamingStrategy.underline_to_camel);//數據庫表映射到實體的命名策略strategy.setTablePrefix("ze_");//設置表前綴不生成strategy.setColumnNaming(NamingStrategy.underline_to_camel);//數據庫表字段映射到實體的命名策略strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter鏈式操作strategy.setRestControllerStyle(true); //restful api風格控制器strategy.setControllerMappingHyphenStyle(true); //url中駝峰轉連字符//strategy.setLogicDeleteFieldName("deleted"); //邏輯刪除字段//自動填充配置//TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);//TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);//ArrayList<TableFill> tableFills = new ArrayList<>();//tableFills.add(gmtCreate);//tableFills.add(gmtModified);//strategy.setTableFillList(tableFills);mpg.setStrategy(strategy);// 6、執行mpg.execute();} }項目地址
https://github.com/xzMhehe/codingce-java/tree/master/mybatis_plus
總結
以上是生活随笔為你收集整理的【Java萌新】MyBatis-Plus案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10redis闪退
- 下一篇: Java助力期末