MyBatis-Plus日常工作學習

螞蟻小哥發表於2021-04-14

一:Mybatis-Plus概述

  MyBatis-Plus (opens new window)(簡稱 MP)是一個 MyBatis (opens new window)的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。國人的驕傲呀!!

(1):特性

  • 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
  • 損耗小:啟動即會自動注入基本 CURD,效能基本無損耗,直接物件導向操作
  • 強大的 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 操作智慧分析阻斷,也可自定義攔截規則,預防誤操作

具體程式碼下載:

git clone https://gitee.com/antLaddie/mybatis_plus_demo.git

二:MapperCRUD介面操作

  我們在Mapper層上使用CRUD時就需要在具體的介面上繼承BaseMapper介面,為Mybatis-Plus啟動時自動解析實體表關係對映轉換為Mybatis內部物件注入容器;其中Searializable為任意型別的主鍵,Mybatis-Plus不推薦使用複合主鍵約定每一張表都有自己的唯一ID主鍵

Mybatis_Plus基本必備註解說明:
    ①:@TableId:    此註解代表當前實體欄位對應資料庫表主鍵
        type:設定主鍵生成型別
        value:設定實體欄位與資料庫欄位對映不一致
    ②:@TableField  此註解代表當前實體欄位對應資料庫表普通欄位
        value:設定實體欄位與資料庫欄位對映不一致
        fill: 設定填充模式
    ③:@TableName   對映到資料庫表名稱
        value:具體對映表名

1:Insert插入方法

// 插入一條記錄  T entity 傳入對應的實體類即可
int insert(T entity);

注意事項:在使用儲存或根據ID查詢、更新、刪除時,主鍵欄位必須新增@TableId

MyBatis-Plus日常工作學習
/**
 * @Auther: xiaoYang
 * @Date: 2021/4/6 12:38
 * @Description: 學生實體類
 */
//下面四個都是lombok外掛註解
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student implements Serializable {

    @TableId    //必須新增此註解代表當前實體的主鍵
    private Long sid;           //學生ID
    private String sname;       //姓名
    private String ssex;        //性別
    private Integer sage;       //年齡
    private String saddress;    //住址
    private Integer isDel;      //是否被刪除 0未刪除 1刪除
    private Date createTime;    //資料行建立時間
    private Date updateTime;    //資料行更新時間
    private Integer version;    //版本(用於樂觀鎖)
}
在實體類上必加@TableId

2:Select查詢方法

  Mapper層上也實現了特別多的基本查詢方法,如id查詢、條件查詢、分頁查詢、統計查詢...

## 引數型別
    型別                               引數名                            描述
Serializable                            id                             主鍵ID
Wrapper<T>                         queryWrapper             實體物件封裝操作類(可以為 null)
Collection<? extends Serializable>    idList                主鍵ID列表(不能為 null 以及 empty)
Map<String, Object>                 columnMap                       表欄位 map 物件
IPage<T>                               page                 分頁查詢條件(可以為 RowBounds.DEFAULT)

## 具體方法
// 根據 ID 查詢
T selectById(Serializable id);
// 根據 entity 條件,查詢一條記錄
// 指定的條件查詢查詢到多條資料則出現異常
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查詢(根據ID 批量查詢)
// 批量查詢 底層使用的是 where xx in ( *** )  IN關鍵字
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根據 entity 條件,查詢全部記錄  全表查詢則傳入null
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查詢(根據 columnMap 條件)
// 傳入map型別,多個鍵值則為  aaa = xxx AND bbb = xxx
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根據 Wrapper 條件,查詢全部記錄
//以鍵值對的形式返回 [ {xx=xx,...},{xx=xx,...} ]
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄。注意: 只返回第一個欄位的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 entity 條件,查詢全部記錄(並翻頁)  分頁後面專門說
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄(並翻頁)  分頁後面專門說
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢總記錄數
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
MyBatis-Plus日常工作學習
// ### 示例 
@Test
    public void selectList() {
        //使用條件構造器模糊查詢帶 %壯%的名稱
        QueryWrapper<Student> wrapper = new QueryWrapper<Student>().like("sname", "壯");
        List<Student> students = studentMapper.selectList(wrapper);
        students.forEach(System.out::println);
    }
Select基本示例

3:Update更新方法

  Mapper也提供了更新方法,可以根據ID來更新一條,或者根據條件查詢更新多條

// 根據 ID 修改    
int updateById(@Param(Constants.ENTITY) T entity);
// 根據 whereEntity 條件,更新記錄
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
MyBatis-Plus日常工作學習
    // 根據 ID 修改    一次更新一個
    // int updateById(@Param(Constants.ENTITY) T entity);
    @Test
    public void updateById() {
        //設定基本資訊
        Student stu = new Student();
        stu.setSname("螞蟻小哥");
        stu.setSsex("男");
        stu.setSaddress("上海浦東");
        stu.setSid(1379438319679049730L);   //必須設定ID 要不然找不到
        int i = studentMapper.updateById(stu);
        System.out.println("更新記錄條數:" + i);
    }

    // 根據 whereEntity 條件,更新記錄  可以一次性更新多個
    // int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
    @Test
    public void update() {
        //設定基本資訊    更改年齡66
        Student stu = new Student();
        stu.setSage(66);
        int i = studentMapper.update(stu, new QueryWrapper<Student>().eq("ssex", "保密"));
        System.out.println("更新記錄條數:" + i);
    }
Update基本示例

4:Delete刪除方法

  Mapper其實也提供了刪除方法,如根據ID刪除、批量刪除、條件刪除....

// 根據 entity 條件,刪除記錄
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 刪除(根據ID 批量刪除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根據 ID 刪除
int deleteById(Serializable id);
// 根據 columnMap 條件,刪除記錄
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
MyBatis-Plus日常工作學習
    // 根據 entity 條件,刪除記錄
    // int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
    @Test
    public void delete() {
        // 刪除名字中帶 %壯% 的名字
        int i = studentMapper.delete(new QueryWrapper<Student>().like("sname", "壯"));
        System.out.println("刪除個數:" + i);
    }

    // 刪除(根據ID 批量刪除)
    // int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
    @Test
    public void deleteBatchIds() {
        // 傳入集合  刪除ID為 2 4 6 8
        int i = studentMapper.deleteBatchIds(Arrays.asList(2, 4, 6, 8));
        System.out.println("刪除個數:" + i);
    }
Delete基本示例

5:Page分頁查詢及分頁外掛

  細心的話,大家會發現,寫完了分頁查詢後卻不起效果,其實這是因為分頁查詢是需要配置Mybatis-Plus指定外掛的;但要注意的是,分頁查詢和我們上面的普通查詢是不一樣的,我們得配置mybatis-plus特有的分頁外掛才可以使用,具體配置如下:

MyBatis-Plus日常工作學習
@Configuration
@MapperScan(basePackages = "cn.xw.mapper")  //對映mapper掃描
public class MybatisPlusConfig {

    //在這個Bean物件裡面配置我們所需的外掛,這裡我們只需要配置一個分頁外掛即可
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //攔截器物件
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //建立分頁外掛 並指定為mysql資料庫方言 也可以通過物件set設定各種屬性
        PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        //配置的每頁最多顯示多少條資料
        pageInterceptor.setMaxLimit(10L);
        // 放入新增分頁攔截器外掛
        interceptor.addInnerInterceptor(pageInterceptor);
        return interceptor;
    }
}
自定義config配置類==>分頁
MyBatis-Plus日常工作學習
@SpringBootTest
public class PageTests {

    @Autowired
    private StudentMapper studentMapper;

    // 根據 entity 條件,查詢全部記錄(並翻頁)
    // IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    @Test
    public void selectPage() {
        //分頁物件
        Page<Student> page = new Page<>(1, 10);
        //分頁查詢
        Page<Student> pageResult = studentMapper.selectPage(page, null);
        System.out.println("總記錄數:" + pageResult.getTotal());
        System.out.println("每頁總數" + pageResult.getSize());
        System.out.println("當前頁:" + pageResult.getCurrent());
        System.out.println("排序欄位資訊:" + pageResult.getOrders());
        pageResult.getRecords().forEach(System.out::println);
    }
    
    // 根據 Wrapper 條件,查詢全部記錄(並翻頁)
    // IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
    @Test
    public void selectMapsPage() {
        //分頁物件
        Page<Map<String, Object>> page = new Page<>(1, 5);
        //分頁查詢
        Page<Map<String, Object>> pageResult = studentMapper.selectMapsPage(page, null);
        System.out.println("總記錄數:" + pageResult.getTotal());
        System.out.println("每頁總數" + pageResult.getSize());
        System.out.println("當前頁:" + pageResult.getCurrent());
        System.out.println("排序欄位資訊:" + pageResult.getOrders());
        List<Map<String, Object>> list = pageResult.getRecords();
        for (Map<String, Object> li : list) {
            System.out.println("姓名:" + li.get("sname") + "  地址:" + li.get("saddress"));
        }
    }
}
使用mybatis-plus外掛來分頁測試

6:Sequence主鍵增長策略及主鍵生成策略

  其實mybatis-plus內建了幾個主鍵增長策略,我們只需要通過@TableId註解裡的type來完成對其設定,也內建了主鍵增長策略

##  ASSIGN_ID(雪花演算法)

  如果我們不設定主鍵型別值,預設則使用 IdType.ASSIGN_ID 策略(自3.3.0起)該策略會使用雪花演算法自動生成主鍵ID,主鍵型別為長整型或字串(分別對應的MySQL的表欄位為BIGINT和VARCHAR)

  該策略使用介面IdentifierGenerator的方法nextId(以實現類為DefaultIdentifierGenerator雪花演算法)

  雪花演算法(雪花)是微博開源的分散式ID生成演算法其核心思想就是:使用一個64位的長整型的數字作為全域性唯一ID。在分散式系統中的應用十分廣泛,且ID引入了時間戳,基本上保持自增的

@Data
public class Student implements Serializable {
    @TableId(type = IdType.ASSIGN_ID)   //使用雪花演算法生成主鍵  不寫也是使用雪花演算法
    private Long sid;           //學生ID
    private String sname;       //姓名
  ......省略
}

##  ASSIGN_UUID(去除了中橫線的UUID)

  如果使用 IdType.ASSIGN_UUID 策略,並重新自動生成排除中劃線的UUID作為主鍵。主鍵型別為String,對應MySQL的表分段為VARCHAR(32)

  該策略使用介面IdentifierGenerator的方法nextUUID

@Data
public class Student implements Serializable {
    @TableId(type = IdType.ASSIGN_UUID)   //使用了UUID(沒有中橫線)的方式生成主鍵 注意的是主鍵欄位是varchar(32)才行
    private Long sid;           //學生ID
    private String sname;       //姓名
  ......省略
}

##  AUTO(資料庫自增長 適用於MySQL)

   對於MySQL適用於這種自增長,但是我們在建立資料庫欄位主鍵時別忘了設定auto_increment

@Data
public class Student implements Serializable {
    // 對於像MySQL這樣的支援主鍵自動遞增的資料庫,我們可以使用IdType.AUTO策略
    @TableId(type = IdType.AUTO)   // 特別注意 資料庫要加 auto_increment
    private Long sid;           //學生ID
    private String sname;       //姓名
  ......省略
}

##  INPUT(插入前自行設定主鍵自增)

  針對有序列的資料庫:Oracle,SQLServer等,當需要建立一個自增序列時,需要用到序列

  在Oracle 11g中,設定自增擴,需要先建立序列(SQUENCE)再建立一個觸發器(TRIGGER)

  在Oracle 12c中,只需要使用IDENTITY屬性就可以了,和MySQL一樣簡單

     Mybatis -Plus已經定義好了常見的資料庫主鍵序列,我們首先只需要在@Configuration類中定義好@Bean:

  Mybatis -Plus內建瞭如下資料庫主鍵序列(如果內建支援不滿足你的需求,可實現IKeyGenerator介面來進行擴充套件):

  DB2KeyGenerator、H2KeyGenerator、KingbaseKeyGenerator、OracleKeyGenerator、PostgreKeyGenerator

// 配置類
@SpringBootConfiguration
@MapperScan(basePackages = "cn.xw.mapper")  //對映包掃描
public class MybatisPlusConfig {
    // 配置主鍵序列方式
    @Bean
    public IKeyGenerator keyGenerator() {
        //建立Oracle序列
        return new OracleKeyGenerator();
    }
}

  然後實體類配置主鍵Sequence,指定主鍵策略為IdType.INPUT即可;支援父類定義@KeySequence子類使用,這樣就可以幾個表共享一個Sequence

  如果主鍵是String型別的,也可以使用;如何使用序列作為主鍵,但是實體主鍵型別是字串開頭,表的主鍵是varchar2,但是需要從序列中取值

  實體定義@KeySequence註解clazz指定型別String.class

  實體定義主鍵的型別字串

  注意:oracle的序列返回的是Long型別,如果主鍵型別是Integer,可能會引起ClassCastException

@KeySequence(value = "SQL_TEST", clazz = String.class)
public class Student implements Serializable {
    @TableId(type = IdType.INPUT)
    private Long sid;           //學生ID
    private String sname;       //姓名
    ...後面省略
}

 7:自動填充功能

   我們試想這樣一個場景,我們每次新增資料時有個欄位是記錄資料建立時間的createTime;那麼我們修改資料時是要由updateTime來記錄我們什麼時候修改了資料;前提我們使用自動填充功能實現時資料庫建立型別不要以timestamp時間戳,因為這樣資料庫層面就可以實現此功能

  自動填充功能不光可以實現時間的自動填充,其它的我們有需求都是可以實現的

   實現元物件處理器介面:com.baomidou.mybatisplus.core.handlers.MetaObjectHandler

  註解填充欄位 @TableField(.. fill = FieldFill.INSERT) 生成器策略部分也可以配置

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@TableName(value = "student")   // 資料庫表名稱
public class Student implements Serializable {
    //雪花ID
    @TableId(type = IdType.ASSIGN_ID)private Long sid;           //學生ID
    private String sname;       //姓名
    private String ssex;        //性別
    private Integer sage;       //年齡
    private String saddress;    //住址
    private Integer isDel;      //是否被刪除 0未刪除 1刪除
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;    //資料行建立時間
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;    //資料行更新時間
    private Integer version;    //版本(用於樂觀鎖)
}
MyBatis-Plus日常工作學習
@Slf4j  //日誌
@Component  //加入容器
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 新增資料時的填充方案
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        Date currentDate = new Date();
        // 插入建立時間
        if (metaObject.hasSetter("createTime")) {
            this.strictInsertFill(metaObject, "createTime", Date.class, currentDate);
        }
        // 同時設定修改時間為當前插入時間
        if (metaObject.hasSetter("updateTime")) {
            this.strictUpdateFill(metaObject, "updateTime", Date.class, currentDate);
        }
        //this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)
    }

    // 更新資料時的填充方案
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date()); // 起始版本 3.3.0(推薦使用)
    }
}
配置自定義handler,填充類實現方案
public enum FieldFill {  //取值範圍
    //預設不處理
    DEFAULT,
    //插入填充欄位
    INSERT,
    //更新填充欄位
    UPDATE,
    //插入和更新填充欄位
    INSERT_UPDATE
}

8:邏輯刪除

  其實邏輯刪除不是真正來刪除具體的資料,而是要對刪除的資料使用某個欄位來記錄當前資料是否被刪除了,我們通常使用 is_del 來記錄 0 代表未刪除 1 代表被刪除;此時我的表是存在 is_del 欄位的,所以我們就可以認為每次刪除就等於更新 is_del 欄位值;但是我們得對mybatis_plus配置後才可以生效

在application.yml裡配置mybatis-plus:標紅的才是我們要配置的
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 日誌輸出到控制檯 global-config: db-config: logic-delete-field: isDel # 全域性邏輯刪除的實體欄位名(since 3.3.0,配置後可以忽略實體上不配置 @TableLogic) logic-not-delete-value: 0 # 邏輯未刪除值(預設為 0) logic-delete-value: 1 # 邏輯已刪除值(預設為 1)
在實體類上新增 @TableLogic 註解:
@TableName(value = "student")
public class Student implements Serializable {
//使用雪花演算法生成主鍵 不寫也是使用雪花演算法
@TableId(type = IdType.ASSIGN_ID)
@TableField(value = "sid")
private Long sid; //學生ID
  ......省略部分
@TableLogic // 在配置裡配置了logic-delete-field屬性後可不加此註解 在3.3.0版本以上才可以不加
private Integer isDel; //是否被刪除 0未刪除 1刪除
......省略部分
}

  還有一個問題就是,我們在新增資料的時候,我們得設定 is_del 欄位資料值為 0 (未刪除)嗎?其實這可以使用自動填充功能完成,但是最好使用在資料庫定義預設值 is_del  int  default 0

三:Mybatis-Plus外掛

  在學習外掛時首先介紹一下 MybatisPlusInterceptor 它是核心外掛 目前代理了 Executor#query 和 Executor#update 和StatementHandler#prepare 方法

MybatisPlusInterceptor 屬性:
    private List<InnerInterceptor> interceptors = new ArrayList<>();
InnerInterceptor:它是一個介面,我們提供的外掛都將基於此介面來實現功能
    目前以實現此介面的類:
        自動分頁:               PaginationInnerInterceptor
        多租戶:                 TenantLineInnerInterceptor
        動態表名:               DynamicTableNameInnerInterceptor
        樂觀鎖:                 OptimisticLockerInnerInterceptor
        sql效能規範:            IllegalSQLInnerInterceptor
        防止全表更新與刪除:       BlockAttackInnerInterceptor

  注意:

  使用多個功能需要注意順序關係,建議使用如下順序

  • 多租戶,動態表名
  • 分頁,樂觀鎖
  • sql效能規範,防止全表更新與刪除

   總結: 對sql進行單次改造的優先放入,不對sql進行改造的最後放入#使用方式(以分頁外掛舉例)

1:分頁外掛

  在上面的分頁查詢有過介紹

2:樂觀鎖外掛

  樂觀鎖採用了更加寬鬆的加鎖機制,他相信其它人不會來和它爭搶鎖的,所以樂觀鎖更傾向於開發運用,不對資料進行加鎖,可以提高資料庫的效能,而悲觀鎖就有點悲觀了,利用資料庫的鎖機制實現,把要操作的資料或者表進行加鎖,其它人不給操作,只有等它操作完了才輪到後面人使用,這往往來說就加大了資料庫的效能開銷

在mybatis-plus裡的樂觀鎖實現方式:
    ①:取出記錄時,獲取當前version欄位值
    ②:更新時,帶上version欄位值
    ③:執行更新時比對獲取的version和資料庫已有的version是否一致
        set version = newVersion where version = oldVersion
    ④:如果提交的version和資料庫裡的version不對應則更新失敗

首先配置樂觀鎖外掛:

@SpringBootConfiguration    //宣告為配置類
@MapperScan(basePackages = "cn.xw.mapper")  //對映包掃描
public class MybatisPlusConfig {
    //Mybatis_plus攔截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //建立外掛核心類物件(攔截器)
        MybatisPlusInterceptor plusInterceptor = new MybatisPlusInterceptor();
        //建立樂觀鎖外掛  對更新生效  並新增到核心外掛物件實力裡
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor 
                = new OptimisticLockerInnerInterceptor();
        plusInterceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        //返回
        return plusInterceptor;
    }
}

然後在實體類上的version(名字隨便)一定要加上@Version註解

4:防止全表更新與刪除外掛

  其實我們在進行更新或者刪除資料時可能會一不小心刪除了全部,這都是因為我們忘傳條件,或者全匹配條件,這樣就會造成資料的全部更新或者刪除,這顯然是不可以的,所以mybatis-plus為我們提供了防止全表刪除或者更新外掛

 首先我們去配置類配置 防止全表刪除更新外掛:

@SpringBootConfiguration    //宣告為配置類
@MapperScan(basePackages = "cn.xw.mapper")  //對映包掃描
public class MybatisPlusConfig {

    //Mybatis_plus攔截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        //建立外掛核心類物件(攔截器)
        MybatisPlusInterceptor plusInterceptor = new MybatisPlusInterceptor();
        //建立樂觀鎖外掛  對更新生效  並新增到核心外掛物件實力裡
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor
                = new OptimisticLockerInnerInterceptor();
        plusInterceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        //建立 防止全表更新與刪除外掛(順序必須在樂觀鎖外掛後面)並新增到核心外掛物件實力裡
        BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();
        plusInterceptor.addInnerInterceptor(blockAttackInnerInterceptor);
        //返回
        return plusInterceptor;
    }
}
MyBatis-Plus日常工作學習
    //演示批量刪除或者批量修改
    @Test
    void delTest() {
        int delete = studentMapper.delete(null);
        System.out.println("批量刪除了:" + delete + " 條資料");
        // 防止全表更新與刪除外掛加上後執行批量刪除
        //### The error occurred while executing an update  //解釋:執行更新時發生錯誤
        //### Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: 
     //  Prohibition of full table deletion //解釋禁止全表刪除
    }
測試 防止全表刪除更新外掛

5:總結外掛

  我們在使用外掛時和上述操作大同小異,直接建立指定外掛並add新增到核心外掛物件裡即可

四:條件構造器

  條件構造器抽象類其實是 AbstractWrapper 這個抽象類裡面有特別多的條件方法,而它的實現類有 QueryWrapper 查詢條件構造器和 UpdateWrapper 更新條件構造器,我們在查詢的時候就用QueryWrapper;在接下來的例子中我都以QueryWrapper實現類來說明

具體條件構造器請參考官方文件

MyBatis-Plus日常工作學習
allEq:         多條件匹配查詢全部      isNull:        欄位 IS NULL                  
eq:            等於 =                    isNotNull:     欄位 IS NOT NULL               
ne:            不等於 <>                 in:            欄位 IN (v0, v1, ...)          
gt:            大於 >                    notIn:         欄位 NOT IN (v0, v1, ...)      
ge:            大於等於 >=                or:            拼接 OR                       
lt:            小於 <                    andAND 巢狀                      
le:            小於等於 <=               inSql:          欄位 IN ( sql語句 )           
betweenBETWEEN 值1 AND 值2       notInSql:       欄位 NOT IN ( sql語句 )       
notBetween:    NOT BETWEEN 值1 AND 值2   groupBy:        分組:GROUP BY 欄位, ...      
likeLIKE '%值%'               orderByAsc:     排序:ORDER BY 欄位, ... ASC  
notLike:       NOT LIKE '%值%'           orderByDesc:    排序:ORDER BY 欄位, ... DESC 
likeLeft:      LIKE '%值'                orderBy:        排序:ORDER BY 欄位, ...      
likeRight:     LIKE '值%'                havingHAVING ( sql語句 )  
                                                                       
func:          func 方法(主要方便在出現if...else下呼叫不同方法能不斷鏈)
nested:        正常巢狀 不帶 AND 或者 OR
apply:         拼接 sql
last:          無視優化規則直接拼接到 sql 的最後
exists:        拼接 EXISTS ( sql語句 )
notExists:     拼接 NOT EXISTS ( sql語句 )
AbstractWrapper條件查詢方法

 1:QueryWrapper查詢條件構造器

⭐ allEq  =  ;  eq = 

    allEq(Map<R, V> params)
    allEq(Map<R, V> params, boolean null2IsNull)
    allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
    eq(R column, Object val)
    eq(boolean condition, R column, Object val)

    引數說明:
    Map<R, V> params :傳入Map鍵值對 R 表欄位 V 值
    boolean null2IsNull:傳入的map鍵值對中,為true是,如果有鍵值為null的話是否以isNull查詢
    是否引數為 null 自動執行 isNull 方法, false 則忽略這個欄位
    boolean condition:執行條件預設true,false 忽略我們條件
MyBatis-Plus日常工作學習
    // 多條件查詢匹配條件 allEq
    @Test
    void allEqTest() {
        //建立查詢物件條件
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        //建立查詢條件引數
        Map<String, Object> map = new HashMap<>();
        map.put("sage", 20);
        map.put("ssex", null);
        wrapper.allEq(true, map, true);
        List<Student> students = studentMapper.selectList(wrapper);
        students.forEach(System.out::println);
    }

    // 條件查詢  等於 =
    @Test
    void eqTest() {
        //建立查詢物件條件全部為男生資料 並查詢
        List<Student> students = studentMapper
                .selectList(new QueryWrapper<Student>().eq("ssex", "男"));
        students.forEach(System.out::println);
    }
allEq、eq測試

⭐ ne <> ; gt > ; ge >= ; lt < ; le <= 

ne(R column, Object val)
ne(boolean condition, R column, Object val)
gt(R column, Object val)
gt(boolean condition, R column, Object val)
ge(R column, Object val)
ge(boolean condition, R column, Object val)
lt(R column, Object val)
lt(boolean condition, R column, Object val)
le(R column, Object val)
le(boolean condition, R column, Object val)
MyBatis-Plus日常工作學習
 // 都差不多,以 gt為例
    // ne <> ; gt > ; ge >= ; lt < ; le <= 查詢
    // .... FROM student WHERE (sage > ? AND ssex <> ?)
    @Test
    void gtTest(){
        List<Student> students = studentMapper
                .selectList(new QueryWrapper<Student>()
                        .gt("sage",21)
                        .ne("ssex","保密"));
        students.forEach(System.out::println);
    }
測試程式碼

 ⭐ 綜合使用

MyBatis-Plus日常工作學習
 //綜合編寫
    @Test
    void sumTest(){
        //建立查詢物件條件
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        //條件:查詢學生id在5~15之間
        wrapper.between("sid",4,15);
        //條件:模糊查詢學生中不帶 %壯% 子的名字
        wrapper.notLike("sname","%壯%");
        List<Student> students = studentMapper.selectList(wrapper);
        students.forEach(System.out::println);
    }
綜合操作

 五:執行 SQL 分析列印

  該功能依賴 p6spy 元件,可以完美輸出列印SQL執行時常及其它資訊

<!--效能測試-->
<dependency>
  <groupId>p6spy</groupId>
  <artifactId>p6spy</artifactId>
  <version>3.9.1</version>
</dependency>

  更改配置application.yml配置:

spring:
  # 設定資料庫連線資訊
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://localhost:3306/demo_m......
    .....

  在resources資源目錄下建立spy.properties配置:

MyBatis-Plus日常工作學習
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,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
spy.properties 配置檔案

然後就和我們正常使用一樣來執行SQL語句查詢等其它操作;在控制檯會列印當前的執行sql執行時間等資訊 如下列印:

Consume Time:17 ms 2021-04-12 19:37:25
Execute SQL:SELECT sid ...... FROM student WHERE (sid BETWEEN 4 AND 15 AND sname NOT LIKE '%%壯%%')

 六:程式碼生成器

  AutoGenerator 是 MyBatis-Plus 的程式碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個模組的程式碼,極大的提升了開發效率

  在使用程式碼生成器之前我們需要匯入相應座標

    <!--程式碼生成器座標  我mybatis-plus版本是3.4.1-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--下面兩個根據自己選擇的模板匯入其中一個即可-->
        <!--模板座標 freemarker-->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>
        <!--模板座標 velocity-engine-core-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>

在學習程式碼生成器之前資料的準備

程式碼生成器原始碼搜尋下載  程式碼生成器具體配置 

MyBatis-Plus日常工作學習
public void fun() {
        System.out.println("java版本號:" + System.getProperty("java.version")); // java版本號
        System.out.println("Java提供商名稱:" + System.getProperty("java.vendor")); // Java提供商名稱
        System.out.println("Java提供商網站:" + System.getProperty("java.vendor.url")); // Java提供商網站
        System.out.println("jre目錄:" + System.getProperty("java.home")); // Java,哦,應該是jre目錄
        System.out.println("Java虛擬機器規範版本號:" + System.getProperty("java.vm.specification.version")); // Java虛擬機器規範版本號
        System.out.println("Java虛擬機器規範提供商:" + System.getProperty("java.vm.specification.vendor")); // Java虛擬機器規範提供商
        System.out.println("Java虛擬機器規範名稱:" + System.getProperty("java.vm.specification.name")); // Java虛擬機器規範名稱
        System.out.println("Java虛擬機器版本號:" + System.getProperty("java.vm.version")); // Java虛擬機器版本號
        System.out.println("Java虛擬機器提供商:" + System.getProperty("java.vm.vendor")); // Java虛擬機器提供商
        System.out.println("Java虛擬機器名稱:" + System.getProperty("java.vm.name")); // Java虛擬機器名稱
        System.out.println("Java規範版本號:" + System.getProperty("java.specification.version")); // Java規範版本號
        System.out.println("Java規範提供商:" + System.getProperty("java.specification.vendor")); // Java規範提供商
        System.out.println("Java規範名稱:" + System.getProperty("java.specification.name")); // Java規範名稱
        System.out.println("Java類版本號:" + System.getProperty("java.class.version")); // Java類版本號
        System.out.println("Java類路徑:" + System.getProperty("java.class.path")); // Java類路徑
        System.out.println("Java lib路徑:" + System.getProperty("java.library.path")); // Java lib路徑
        System.out.println("Java輸入輸出臨時路徑:" + System.getProperty("java.io.tmpdir")); // Java輸入輸出臨時路徑
        System.out.println("Java編譯器:" + System.getProperty("java.compiler")); // Java編譯器
        System.out.println("Java執行路徑:" + System.getProperty("java.ext.dirs")); // Java執行路徑
        System.out.println("作業系統名稱:" + System.getProperty("os.name")); // 作業系統名稱
        System.out.println("作業系統的架構:" + System.getProperty("os.arch")); // 作業系統的架構
        System.out.println("作業系統版本號:" + System.getProperty("os.version")); // 作業系統版本號
        System.out.println("檔案分隔符:" + System.getProperty("file.separator")); // 檔案分隔符
        System.out.println("路徑分隔符:" + System.getProperty("path.separator")); // 路徑分隔符
        System.out.println("直線分隔符:" + System.getProperty("line.separator")); // 直線分隔符
        System.out.println("作業系統使用者名稱:" + System.getProperty("user.name")); // 使用者名稱
        System.out.println("作業系統使用者的主目錄:" + System.getProperty("user.home")); // 使用者的主目錄
        System.out.println("當前程式所在目錄:" + System.getProperty("user.dir")); // 當前程式所在目錄
    }
System.getProperty("xx”);資訊填寫
MyBatis-Plus日常工作學習
package cn.xw;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther: xiaoYang
 * @Date: 2021/4/13 14:29
 * @Description:
 */
public class GeneratorCodeUtils {
    public static void main(String[] args) {

        //設定作者資訊
        String author = "xiaoYang";
        //資料庫URL / username / password
        String url = "jdbc:mysql://localhost:3306/demo_mp?useSSL=true&useUnicode=true&" +
                "characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&" +
                "useLegacyDatetimeCode=false&serverTimezone=GMT%2B8";
        String username = "root";
        String password = "123";
        //這個include 和exclude只能存在一個
        String[] include = {"student"};
        String[] exclude = {};
        //樂觀鎖屬性名稱 和資料庫表欄位保持一致
        String version = "version";
        //邏輯刪除屬性名稱 和資料庫表欄位保持一致
        String isDel = "is_del";

        //程式碼生成器
        AutoGenerator autoGenerator = new AutoGenerator();
        //全域性相關配置
        GlobalConfig gc = new GlobalConfig();
        String propertyPath = System.getProperty("user.dir");
        gc.setOutputDir(propertyPath + "./src/main/java")
                .setAuthor(author)
                .setDateType(DateType.ONLY_DATE)
                .setEnableCache(false)
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setOpen(false)
                .setServiceName("%sService");
        autoGenerator.setGlobalConfig(gc);
        //資料來源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUrl(url);
        dsc.setUsername(username);
        dsc.setPassword(password);
        autoGenerator.setDataSource(dsc);
        //包配置
        PackageConfig pgc = new PackageConfig();
        pgc.setParent("cn.xw");
        autoGenerator.setPackageInfo(pgc);
        //自定義配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
            }
        };
        String templatePath = "/templates/mapper.xml.ftl";
        ArrayList<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出檔名 , 如果你 Entity 設定了前字尾、此處注意 xml 的名稱會跟著發生變化!!
                return propertyPath + "/src/main/resources/mapper/" + pgc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        autoGenerator.setCfg(cfg);
        //模板資訊配置
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        autoGenerator.setTemplate(templateConfig);

        //其它資訊配置
        //策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setInclude(include);
        //排除生成的表名稱,就是寫資料庫表名稱 String ... include
        strategy.setExclude(exclude);
        //strategy.setFieldPrefix("");
        strategy.setTablePrefix("");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        //表填充欄位
        List<TableFill> fill = new ArrayList<>();
        fill.add(new TableFill("create_time", FieldFill.INSERT));
        fill.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));
        strategy.setTableFillList(fill);
        strategy.setVersionFieldName(version);
        strategy.setLogicDeleteFieldName(isDel);
        autoGenerator.setStrategy(strategy);
        autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
        autoGenerator.execute();
    }
}
如果只是單純想快速生成,就複雜這裡面程式碼測試跑通就可以了

程式碼生成器具體詳細註釋:

public static void main(String[] args) {
        //記得生成成功之後,在測試執行的時候要在主啟動類上新增@MapperScan(value = “”)
        //##################    基本資訊準備    ##################
        //獲取當前程式所在目錄 如:h://demo_mybatis_test
        String propertyPath = System.getProperty("user.dir");

        //建立程式碼生成器例項物件 (主要)
        AutoGenerator autoGenerator = new AutoGenerator();

        //##################   全域性相關配置   ##################
        GlobalConfig gc = new GlobalConfig();
        //生成檔案的輸出目錄【預設 D:\\ 盤根目錄】
        gc.setOutputDir(propertyPath + "./src/main/java");
        //設定作者資訊
        gc.setAuthor("xiaoYang");
        //時間型別對應策略
        // ONLY_DATE:使用 java.util.date 代替
        // SQL_PACK:使用 java.sql 包下的
        // TIME_PACK:使用 java.time 包下的 java8 新的時間型別
        gc.setDateType(DateType.ONLY_DATE);
        //是否在xml中新增二級快取配置 預設false
        gc.setEnableCache(false);
        //是否在XML裡建立 ResultMap開啟 就是建立<resultMap></resultMap>標籤  預設false
        gc.setBaseResultMap(true);
        //是否在XML裡建立 columnList開啟 就是建立<sql> 表全部欄位 </sql>標籤 預設false
        gc.setBaseColumnList(true);
        //是否開啟輸出目錄 就是說建立完是否彈出window資料夾位置
        gc.setOpen(false);
        //!!!各層檔名稱方式,註釋的全部是預設的 例如: I%sService 生成 IStudentService
        //gc.setEntityName("%s");
        //gc.setMapperName("%sMapper");
        //gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        //gc.setServiceImplName("%sServiceImpl");
        //gc.setControllerName("%sController");
        //實體屬性 Swagger2 註解
        //gc.setSwagger2(true);
        // 把全域性配置新增到 程式碼生成器例項裡
        autoGenerator.setGlobalConfig(gc);

        //##################   資料來源配置   ##################
        DataSourceConfig dsc = new DataSourceConfig();
        //資料庫型別
        dsc.setDbType(DbType.MYSQL);
        //設定資料庫驅動 此處是mysql8.0版本
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        // 資料庫連結URL 我這裡使用的是MySQL8的連結URL 一樣的
        dsc.setUrl("jdbc:mysql://localhost:3306/demo_mp?useSSL=true&useUnicode=true&" +
                "characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&" +
                "useLegacyDatetimeCode=false&serverTimezone=GMT%2B8");
        // 設定資料庫使用者名稱
        dsc.setUsername("root");
        // 設定資料庫密碼
        dsc.setPassword("123");
        // 架構名稱 預設就行
        //dsc.setSchemaName("public");
        //自定義型別轉換 寫這個方法是為了mybatis-plus根據資料庫型別自動生成的實體型別不符合我們要求是才自定義
        //當生成的model實體類,java型別不滿足時可以自定義轉換
        dsc.setTypeConvert(new ITypeConvert() {
            //資料庫型別datetime預設生成的java型別為localDateTime, 下面示例要改成Date型別
            //型別轉換(流程型別轉換方法)
            @Override
            public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                //獲取資料庫型別字串轉為小寫
                String t = fieldType.toLowerCase();
                //判斷當前獲取的型別裡是否包含"datetime" 成立的話就轉型別返回
                if (t.contains("datetime")) {
                    System.out.println("型別捕捉datetime 將從LocalDateTime型別轉Date");
                    return DbColumnType.DATE;
                }
                //其它欄位採用預設轉換(非mysql資料庫可以使用其它預設的資料庫轉換器)
                return new MySqlTypeConvert().processTypeConvert(globalConfig, fieldType);
            }
        });
        // 把資料來源配置新增到 程式碼生成器例項裡
        autoGenerator.setDataSource(dsc);

        //##################   包配置   ##################
        PackageConfig pgc = new PackageConfig();
        pgc.setParent("cn.xw")                  //父包名 預設"com.baomidou"
                .setPathInfo(null)              //路徑配置資訊,就是配置各個檔案模板的路徑資訊
                .setModuleName("")              //父包模組名 預設 ”“
                .setEntity("entity")            //實體類包名 預設entity
                .setService("service")          //Service包名 預設”service“
                .setServiceImpl("service.impl") //Service裡面的實現類位置   預設”service.impl“
                .setMapper("mapper")            //Mapper對映包名    預設”mapper“
                .setXml("mapper.xml")           //Mapper XML包名 預設"mapper.xml"
                .setController("controller");   //Controller包名  預設”controller“
        // 把包配置新增到 程式碼生成器例項裡
        autoGenerator.setPackageInfo(pgc);

        //##################   自定義配置   ##################
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // 這裡面可以設定具體的自定義表資訊等等 正常不寫 特殊百度學習
                //https://www.bookstack.cn/read/mybatis-3.3.2/spilt.7.4267953fc3057caf.md
            }
        };
        //注意 freemarker 和 velocity 使用哪個模板就去匯入哪個座標
        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";
        //自定義輸出配置 就是說找到並定位到我們生成的xxx(mapper).xml在哪裡了
        ArrayList<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出檔名 , 如果你 Entity 設定了前字尾、此處注意 xml 的名稱會跟著發生變化!!
                return propertyPath + "/src/main/resources/mapper/" + pgc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        //設定自定義輸出檔案(就是上面幾行我們配置的)
        cfg.setFileOutConfigList(focList);
        // 把自定義配置新增到 程式碼生成器例項裡
        autoGenerator.setCfg(cfg);

        //##################   模板資訊配置   ##################
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        //把模板資訊配置新增到 程式碼生成器例項裡
        autoGenerator.setTemplate(templateConfig);

        //##################   其它資訊配置   ##################
        //策略配置
        StrategyConfig strategy = new StrategyConfig();
        //資料庫表對映到實體類的命名策略 此時設定下劃線轉駝峰命名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //資料庫表欄位對映到實體欄位的命名策略  此時設定下劃線轉駝峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //setInclude和setExclude只能存在一個,否則某一個為空
        //setInclude必須寫需要生成的資料庫表
        //setExclude根據我們連線的資料庫,排除哪個表不生產,其它全生成
        //需要生成的表名稱,就是寫資料庫表名稱 String ... include
        strategy.setInclude("student");
        //排除生成的表名稱,就是寫資料庫表名稱 String ... include
        //strategy.setExclude("teacher");
        //忽略表欄位字首
        strategy.setFieldPrefix("s");
        // 忽略表名的字首
        strategy.setTablePrefix("");
        // 是否跳過檢視
        strategy.setSkipView(true);
        //使用LomBok 預設false ,設定true注意要匯入lombok座標
        strategy.setEntityLombokModel(true);
        //生成的Controller層使用Rest風格 預設不使用
        strategy.setRestControllerStyle(true);
        //公共父類 如果你有自己的baseController的控制器可以寫上
        //strategy.setSuperControllerClass("你自己的父類控制器,沒有就不用設定!");
        // 寫於父類中的公共欄位
        strategy.setSuperEntityColumns("id");
        //表填充欄位
        List<TableFill> fill = new ArrayList<>();
        fill.add(new TableFill("create_time", FieldFill.INSERT));
        fill.add(new TableFill("update_time", FieldFill.INSERT_UPDATE));
        strategy.setTableFillList(fill);
        //樂觀鎖屬性名稱
        strategy.setVersionFieldName("version");
        //邏輯刪除屬性名稱
        strategy.setLogicDeleteFieldName("is_del");
        
        //把策略配置新增到 程式碼生成器例項裡
        autoGenerator.setStrategy(strategy);
        //設定那種模板引擎
        autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
        // 執行生成
        autoGenerator.execute();
    }

.

相關文章