Mybatis-Plus使用整理


  MyBatis-Plus是一個 Mybatis 的增強工具,在 Mybatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生;

  官網:[https://baomidou.com/]

  • MyBatis-Plus是怎么增強的呢?

  已經封裝好了一些crud方法,我們不需要再寫xml了,直接調用這些方法就行,類似JPA但優於JPA;

  簡介:[https://mp.baomidou.com/guide/]   

 

  • 導入依賴
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
​
<!--mybatis plus和springboot整合-->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.4.1</version>
</dependency>

  

  • MyBatis-Plus配置控制台打印日志
#配置mybatis plus打印sql日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

  

  • BaseMapper使用

  Mapper 繼承該接口后,無需編寫 mapper.xml 文件,即可獲得CRUD功能;

  API使用參考源碼:com.baomidou.mybatisplus.core.mapper.BaseMapper

 

  • QueryWrapper使用

  查詢包裝類,可以封裝多數查詢條件,泛型指定返回的實體類;

  可以封裝sql對象,包括where條件,order by排序,select哪些字段等等;

  核心API:

eq:等於
ne:不等於
gt:大於
ge:大於等於
lt:小於
le:小於等於
or:拼接or
between:兩個值中間
notBetween:不在兩個值中間
like:模糊匹配
notLike:不像
likeLeft:左匹配,eg: like '%a'
likeRight:右邊匹配,eg:like 'a%'
isNull:字段為空
in:in范圍查詢
groupBy:分組
orderByAsc:升序
orderByDesc:降序
having:having查詢

  

  API使用參考源碼:com.baomidou.mybatisplus.core.conditions.query.QueryWrapper

 

  • MyBatis-Plus 常用注解
    • @TableName 用於定義表名  
    • @TableId 用於定義表的主鍵

      • 屬性
value 用於定義主鍵字段名
type 用於定義主鍵類型(主鍵策略 IdType)
      • 主鍵策略    
IdType.AUTO          主鍵自增,系統分配,不需要手動輸入
IdType.NONE          未設置主鍵
IdType.INPUT         需要自己輸入 主鍵值
IdType.ASSIGN_ID     系統分配 ID,用於數值型數據(Long,對應 mysql 中 BIGINT 類型)
IdType.ASSIGN_UUID   系統分配 UUID,用於字符串型數據(String,對應 mysql 中 varchar(32) 類型)
    • @TableField 用於定義表的非主鍵字段
      • 屬性    
value:用於定義非主鍵字段名,用於別名匹配,假如Java對象屬性和數據庫屬性不一樣
​
exist:用於指明是否為數據表的字段, true 表示是,false 為不是,假如某個java屬性在數據庫沒對應的字段則要標記為false
​
fill:用於指定字段填充策略(FieldFill,用的不多)
  字段填充策略:一般用於填充 創建時間、修改時間等字段
  FieldFill.DEFAULT         默認不填充
  FieldFill.INSERT          插入時填充
  FieldFill.UPDATE          更新時填充
  FieldFill.INSERT_UPDATE   插入、更新時填充

  

  • 分頁配置
    • 舊版本寫法(MyBatis-Plus 3.4.0之前)  
@Bean
public PaginationInterceptor paginationInterceptor() {
	return new PaginationInterceptor();
}

  

 

 

   參考源碼:com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor

  

    • 新版本寫法(MyBatis-Plus 3.4.0之后)
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
	MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
	interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

	return interceptor;
}

  

    • 測試分頁:  

    建表sql

CREATE TABLE `banner` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `img` varchar(524) DEFAULT NULL COMMENT '圖片',
  `url` varchar(524) DEFAULT NULL COMMENT '跳轉地址',
  `weight` int(11) DEFAULT NULL COMMENT '權重',
  `version` int(11) DEFAULT '1',
  `deleted` int(11) DEFAULT '0' COMMENT '0是未刪除,1是已經刪除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  

    實體類

@Data
@TableName("banner")
public class BannerDO {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    private String img;

    private String url;

    @TableField("weight")
    private Integer weight;

    @TableField(exist = false)
    private Date createTime;

    /**
     * 樂觀鎖版本號
     */
    @Version
    private Integer version;


    /**
     * 邏輯刪除標識位
     */
    private Integer deleted;

}

  

    分頁測試:

@Test
public void testPage1() {
	// 第1頁,每頁2條
	Page<BannerDO> page = new Page<>(1, 2);
	IPage<BannerDO> bannerDOIPage = bannerMapper.selectPage(page, null);
	log.info("總條數" + bannerDOIPage.getTotal());
	log.info("總頁數" + bannerDOIPage.getPages());
	log.info("當前頁數:" + bannerDOIPage.getCurrent());
	// 獲取當前數據
	log.info(bannerDOIPage.getRecords().toString());
}

  

    執行結果如下:

  

 

 

   啟用分頁插件,MyBatis-Plus會先進行select count(*)對當前表進行統計之后再分頁;

 

    • XML自定義分頁的寫法

    自定義Mapper

public interface BannerMapper extends BaseMapper<BannerDO> {
	IPage<BannerDO> customizeSelectPage(Page<?> page, @Param("weight") int weight);
}

  

    自定義XML

<select id="customizeSelectPage" resultType="BannerDO">
	select id, img, url, weight, version, deleted from banner where weight=#{weight}
</select>

  

    測試分頁:

@Test
public void testPage2() {
	// 第1頁,每頁2條
	Page<BannerDO> page = new Page<>(1, 2);
	IPage<BannerDO> bannerDOIPage = bannerMapper.customizeSelectPage(page, 2);
	log.info("總條數" + bannerDOIPage.getTotal());
	log.info("總頁數" + bannerDOIPage.getPages());
	log.info("當前頁數:" + bannerDOIPage.getCurrent());
	// 獲取當前數據
	log.info(bannerDOIPage.getRecords().toString());
}

  

    執行結果如下:

  

 

 

  參考:[https://mp.baomidou.com/guide/page.html

 

  • MyBatis-Plus 自定義xml

  配置mapper路徑,如果采用默認路徑可以不配

#默認配置路徑
mybatis-plus.mapper-locations=classpath*:/mapper/*Mapper.xml

  

  • MyBatis-Plus 全局配置文件
#配置最新全局配置文件
mybatis-plus.config-location = classpath*:mybatis-config.xml
    • 注意:config-location和configuration不能同時出現,需要注釋配置文件里的相關配置

 

  mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<!--控制台輸出日志-->
		<setting name="logImpl" value="STDOUT_LOGGING"/>
	</settings>
</configuration>

  

  • 配置文件配置 自定義xml映射的包掃描路徑

  eg:

#配置文件配置 自定義sql的包掃描 實體類的路徑
mybatis-plus.type-aliases-package=org.example.manager.model

 

  • MyBatis-Plus下划線轉駝峰配置,默認就是true
mybatis-plus.configuration.map-underscore-to-camel-case=true

  

  • MyBatis-Plus配置全局默認主鍵類型,實體類就不用加 @TableId(value = "id", type = IdType.AUTO)
mybatis-plus.global-config.db-config.id-type=auto

  

  • MyBatis-Plus指定查詢字段

  eg:

List<BannerDO> bannerDOList = bannerMapper.selectList(new QueryWrapper<BannerDO>().select("id", "url"));

  題外話,關於SELECT * 與 SELECT指定字段的區別

    • 網絡I/O

    SELECT * 會查出所有的字段,有些是不需要的,當應用程序和服務器不在同一個局域網時,字段過多會影響網絡傳輸的性能

    • 索引

    在指定字段有索引的情況下,MySql是可以不用讀磁盤的,直接使用索引里面的值就返回結果的;

    但用了SELECT *,這就會有其他列需要從磁盤中讀取才會返回結果,這樣就造成了額外的性能開銷;

 

 

  • MyBatis-Plus樂觀鎖使用  

  樂觀鎖就是每次去拿數據的時候都認為別人不會修改,更新的時候會通過版本來判斷別人是否修改了數據,如果數據被修改了就拒絕更新;

  java中的AtomicXXX原子類是通過CAS實現,CAS即比較並更新,屬於樂觀鎖,性能較悲觀鎖有很大的提高;

  悲觀鎖適合寫操作多的場景,樂觀鎖適合讀操作多的場景,樂觀鎖的吞吐量會比悲觀鎖多;

  數據庫的樂觀鎖大多是基於數據版本 (Version)記錄機制實現;數據版本即為數據增加一個版本標識,在基於數據庫表的版本解決方案中,一般是通過為數據庫表增加一個 “version” 字段來 實現。 讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加一;此時,將提交數據的版本數據與數據,庫表對應記錄的當前版本信息進行比對,如果提交的數據 版本號大於數據庫表當前版本號,則予以更新,否則認為是過期數據;

 

  使用:

  實體類增加version屬性配置

@Version
private Integer version;

  

  增加樂觀鎖插件

//樂觀鎖插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

  

  測試代碼

@Test
public void testOptimisticLocker1() {
	BannerDO bannerDO = new BannerDO();
	//舊版本號,即查詢出來的版本號需要做對比的
	bannerDO.setVersion(1);
	bannerDO.setId(8);
	bannerDO.setUrl("www.baidu.com");
	bannerMapper.updateById(bannerDO);
}

public void testOptimisticLocker2() {
	BannerDO bannerDO = new BannerDO();
	//舊版本號,即查詢出來的版本號需要做對比的
	bannerDO.setVersion(1);
	bannerDO.setId(8);
	bannerDO.setUrl("www.baidu.com");
	bannerMapper.updateById(bannerDO);
}

  

    testOptimisticLocker1執行前,數據庫表中的數據;

  

 

     執行testOptimisticLocker1

  

 

   

 

    執行testOptimisticLocker2,更新失敗

  

 

    注意:

    • 樂觀鎖數據類型支持int,integer,long,timestamp;
    • 僅支持updateById和update方法

 

  • MyBatis-Plus 邏輯刪除配置使用

  邏輯刪除只不過是更新了標記,不會真正的物理刪除;

  使用方式:

    • 數據庫增加邏輯刪除的標識字段,如deleted,0是未刪除,1表示刪除;
    • 實體類增加屬性配置@TableLogic 或者 在配置文件增加指定
@TableLogic
private Integer deleted;
    • 配置文件新增配置
#刪除是1
mybatis-plus.global-config.db-config.logic-delete-value=1
#未刪除是0
mybatis-plus.global-config.db-config.logic-not-delete-value=0
#邏輯刪除的全局標識字段,如果java實體類沒加注解@TableLogic,則可以配置這個
mybatis-plus.global-config.db-config.logic-delete-field=deleted

  

   測試代碼:

public void testDeleteById() {
	int rtn = bannerMapper.deleteById(8);
	log.info("rtn:{}", rtn);
}

  

  執行結果:  

  

 

 

   打印的sql為update,而不是delete;

  

 

 

 

  • Mybatis-Plus-Generator 代碼自動生成工具使用

  AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模塊的代碼,極大的提升了開發效率;
  底層是模板引擎技術,可以自定義生成的java類模板;

  導入依賴

<!-- 代碼自動生成依賴 begin -->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-generator</artifactId>
	<version>3.4.1</version>
</dependency>
<!-- velocity -->
<dependency>
	<groupId>org.apache.velocity</groupId>
	<artifactId>velocity-engine-core</artifactId>
	<version>2.0</version>
</dependency>
<!-- 代碼自動生成依賴 end-->

  

  使用如下,配置按需修改:

public class MyBatisPlusGenerator {
    public static void main(String[] args) {
        //1. 全局配置
        GlobalConfig config = new GlobalConfig();
        // 是否支持AR模式
        config.setActiveRecord(true)
                // 作者
                .setAuthor("")
                // 生成路徑,最好使用絕對路徑
                .setOutputDir("")
                // 文件覆蓋
                .setFileOverride(true)
                // 主鍵策略
                .setIdType(IdType.AUTO)
                // 數據庫時間類型
                .setDateType(DateType.ONLY_DATE)
                // 設置生成的service接口的名字的首字母是否為I,默認Service是以I開頭的
                .setServiceName("%sService")
                // 實體類結尾名稱
                .setEntityName("%sDO")
                // 生成基本的resultMap
                .setBaseResultMap(true)
                // 不使用AR模式
                .setActiveRecord(false)
                // 生成基本的SQL片段
                .setBaseColumnList(true);

        //2. 數據源配置
        DataSourceConfig dsConfig = new DataSourceConfig();
        // 設置數據庫類型
        dsConfig.setDbType(DbType.MYSQL)
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUrl("")
                .setUsername("")
                .setPassword("");

        //3. 策略配置globalConfiguration中
        StrategyConfig stConfig = new StrategyConfig();

        //全局大寫命名
        stConfig.setCapitalMode(true)
                // 數據庫表映射到實體的命名策略
                .setNaming(NamingStrategy.underline_to_camel)
                // 使用lombok
                .setEntityLombokModel(true)
                // 使用restcontroller注解
                .setRestControllerStyle(true)
                // 生成的表, 支持多表一起生成,以數組形式填寫
                // 兩個方式,直接寫,或者使用命令行輸入
                //.setInclude("");
                .setInclude(scanner("表名,多個英文逗號分割").split(","));

        //4. 包名策略配置
        PackageConfig pkConfig = new PackageConfig();
        pkConfig.setParent("org.example.manager")
                .setMapper("mapper")
                .setService("service")
                .setController("controller")
                .setEntity("model")
                .setXml("mapper");
        //5. 整合配置
        AutoGenerator ag = new AutoGenerator();
        ag.setGlobalConfig(config)
                .setDataSource(dsConfig)
                .setStrategy(stConfig)
                .setPackageInfo(pkConfig);

        //6. 執行操作
        ag.execute();
        System.out.println("======= 代碼生成完畢  ========");
    }
    
    /**
     * <p>
     * 讀取控制台內容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("請輸入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("請輸入正確的" + tip + "!");
    }
}

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM