Mybatis Plus的使用(Mybatis增強工具)- Mybatis從學習到忘記

概述

如果你是剛剛學習完Mybatis那麼恭喜你,你竟然在起步階段,就發現了一款可以讓Mybatis起飛的東西;如果你是Mybatis熟客,或者是會使用Mybatis-generator、Mybatis-PageHelper、Mybatis通用mapper,那麼也提前恭喜你,你可以放棄這些“散件”,只需要掌握今天這個東西,上面這些過客可以統統說“拜拜”了。Mybatis Plus看似有着一統Mybatis所有工具(插件)集的架勢,那麼等什麼呢,開始吧!

 一、Mybatis-Plus(MP)簡介

  1. 潤物無聲:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑。
  2. 效率至上:只需簡單配置,即可快速進行 CRUD 操作,從而節省大量時間。
  3. 豐富功能:熱加載、代碼生成、分頁、性能分析等功能一應俱全。
  4. 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
  5. 損耗小:啓動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作
  6. 強大的 CRUD 操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
  7. 支持 Lambda 形式調用:通過 Lambda 表達式,方便的編寫各類查詢條件,無需再擔心字段寫錯
  8. 支持主鍵自動生成:支持多達 4 種主鍵策略(內含分佈式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
  9. 支持 ActiveRecord 模式:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作
  10. 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  11. 內置代碼生成器:採用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用
  12. 內置分頁插件:基於 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之後,寫分頁等同於普通 List 查詢
  13. 分頁插件支持多種數據庫:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多種數據庫
  14. 內置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啓用該功能,能快速揪出慢查詢
  15. 內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
  • MP經典主圖:

核心配圖

二、安裝

Spring Boot項目添加Mybatis-plus的依賴如下:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.2</version>
</dependency>

Spring MVC項目添加Mybatis-plus的依賴如下:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.1.2</version>
</dependency>

三、配置

3.1 Spring Boot 工程:配置 MapperScan 註解

@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(QuickStartApplication.class, args);
    }
}

3.2 Spring MVC 工程:

3.2.1 配置 MapperScan

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.baomidou.mybatisplus.samples.quickstart.mapper"/>
</bean>

3.2.2 調整 SqlSessionFactory 爲 MyBatis-Plus 的 SqlSessionFactory

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

MyBatis-Plus 提供了大量的個性化配置來滿足不同複雜度的工程,大家可根據自己的項目按需取用,詳細配置請參考官方配置一文,詳細的註解請參考官方註解一文。

四、核心功能

4.1 代碼生成器(很好用的)

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

添加依賴

  • 添加 代碼生成器 依賴
  • MyBatis-Plus 從 3.0.3 之後移除了代碼生成器與模板引擎的默認依賴,需要手動添加代碼生成器的依賴:
  • <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>latest-version</version>
    </dependency>
    
  • 添加 模板引擎 依賴,MyBatis-Plus 支持 Velocity(默認)、Freemarker、Beetl,用戶可以選擇自己熟悉的模板引擎,如果都不滿足您的要求,可以採用自定義模板引擎。
  • Velocity(默認):
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>latest-velocity-version</version>
</dependency>
  • Freemarker:
  • <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>latest-freemarker-version</version>
    </dependency>
    

注意!如果您選擇了非默認引擎,需要在 AutoGenerator 中 設置模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

官方配置代碼演示:

// 演示例子,執行 main 方法控制檯輸入模塊表名回車自動生成對應項目目錄中
public class CodeGenerator {

    /**
     * <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.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("請輸入正確的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代碼生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("jobob");
        gc.setOpen(false);
        // gc.setSwagger2(true); 實體屬性 Swagger2 註解
        mpg.setGlobalConfig(gc);

        // 數據源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("密碼");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模塊名"));
        pc.setParent("com.baomidou.ant");
        mpg.setPackageInfo(pc);

        // 自定義配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定義輸出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定義配置會被優先輸出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出文件名 , 如果你 Entity 設置了前後綴、此處注意 xml 的名稱會跟着發生變化!!
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判斷自定義文件夾是否需要創建
                checkDir("調用默認方法創建的目錄");
                return false;
            }
        });
        */
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定義輸出模板
        //指定自定義模板路徑,注意不要帶上.ftl/.vm, 會根據使用的模板引擎自動識別
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        // 公共父類
        strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
        // 寫於父類中的公共字段
        strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多個英文逗號分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

不知道什麼原因我運行後,各包能創建出來,文件總是創建不出來,使用2.x的版本倒是可以創建。更多詳細的代碼生成器配置,請參考代碼生成器配置一文。

4.2 CRUD 接口(MP的核心功能)

4.2.1 Mapper CRUD 接口

  • 通用 CRUD 封裝BaseMapper 接口,爲 Mybatis-Plus 啓動時自動解析實體表關係映射轉換爲 Mybatis 內部對象注入容器
  • 泛型 T 爲任意實體對象
  • 參數 Serializable 爲任意類型主鍵 Mybatis-Plus 不推薦使用複合主鍵約定每一張表都有自己的唯一 id 主鍵
  • 對象 Wrapper條件構造器

其實我們真正在使用Mybatis時候核心就是使用接口編程,再使用xml的實行去實現接口,MP幫助我們創建了大量的公共接口和實現,我們只需要再在自己的Mapper接口文件繼承BaseMapper接口即可使用其內部的各CRUD方法了。提供的方法如下:

//// 插入一條記錄
int insert(T entity);

// 根據 ID 刪除
int deleteById(Serializable id);
// 根據 columnMap 條件,刪除記錄,  參數爲表字段 map 對象
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根據 entity 條件,刪除記錄
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 刪除(根據ID 批量刪除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

// 根據 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);
// 根據 whereEntity 條件,更新記錄
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

// 根據 ID 查詢
T selectById(Serializable id);
// 查詢(根據ID 批量查詢)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 查詢(根據 columnMap 條件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根據 entity 條件,查詢一條記錄
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢總記錄數
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 entity 條件,查詢全部記錄
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄
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);

4.2.2 Service CRUD 接口

  • 通用 Service CRUD 封裝IService 接口,進一步封裝 CRUD 採用 get 查詢單行 remove 刪除 list 查詢集合 page 分頁 前綴命名方式區分 Mapper 層避免混淆,
  • 泛型 T 爲任意實體對象
  • 建議如果存在自定義通用 Service 方法的可能,請創建自己的 IBaseService 繼承 Mybatis-Plus 提供的基類
  • 對象 Wrapper條件構造器

MP對service層也做了大量公共方法的定義,我們只需要在自己的Service接口中繼承MP的IService,即可擁有比mapper更多的方法操作數據庫。Service層提供的方法如下:

// 插入一條記錄(選擇字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)  @param batchSize  插入批次數量
boolean saveBatch(Collection<T> entityList, int batchSize);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

// 根據 ID 刪除
boolean removeById(Serializable id);
// 根據 columnMap 條件,刪除記錄
boolean removeByMap(Map<String, Object> columnMap);
// 根據 entity 條件,刪除記錄
boolean remove(Wrapper<T> queryWrapper);
// 刪除(根據ID 批量刪除)
boolean removeByIds(Collection<? extends Serializable> idList);

// 根據 ID 選擇修改
boolean updateById(T entity);
// 根據 whereEntity 條件,更新記錄
boolean update(T entity, Wrapper<T> updateWrapper);
// 根據ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
// TableId 註解存在更新記錄,否插入一條記錄
boolean saveOrUpdate(T entity);

// 根據 ID 查詢
T getById(Serializable id);
// 查詢(根據ID 批量查詢)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查詢(根據 columnMap 條件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 根據 Wrapper,查詢一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據 Wrapper,查詢一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根據 Wrapper,查詢一條記錄
Object getObj(Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢總記錄數
int count(Wrapper<T> queryWrapper);
// 查詢列表
List<T> list(Wrapper<T> queryWrapper);
// 翻頁查詢
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 查詢列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 根據 Wrapper 條件,查詢全部記錄
List<Object> listObjs(Wrapper<T> queryWrapper);
// 翻頁查詢
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

4.2.3 條件構造器

Mapper層和Service層的接口中看到了許多Wrapper(條件構造器),它可以想象成它一個創建where後面所有語句的對象,它通過各種方法可以創建出各種where語句中的“條件”,所以叫他條件構造器。

  • 以下出現的第一個入參boolean condition表示該條件是否加入最後生成的sql中
  • 以下代碼塊內的多個方法均爲從上往下補全個別boolean類型的入參,默認爲true
  • 以下出現的泛型Param均爲Wrapper的子類實例(均具有AbstractWrapper的所有方法)
  • 以下方法在入參中出現的R爲泛型,在普通wrapper中是String,在LambdaWrapper中是函數(例:Entity::getId,Entity爲實體類,getId爲字段idgetMethod)
  • 以下方法入參中的R column均表示數據庫字段,當R具體類型爲String時則爲數據庫字段名(字段名是數據庫關鍵字的自己用轉義符包裹!)!而不是實體類數據字段名!!!,另當R具體類型爲SFunction時項目runtime不支持eclipse自家的編譯器!!!
  • 以下舉例均爲使用普通wrapper,入參爲MapList的均以json形式表現!
  • 使用中如果入參的Map或者List,則不會加入最後生成的sql中!!!
  • 有任何疑問就點開源碼看,看不懂函數點擊我學習新知識

警告:

不支持以及不贊成在 RPC 調用中把 Wrapper 進行傳輸

  1. wrapper 很重
  2. 傳輸 wrapper 可以類比爲你的 controller 用 map 接收值(開發一時爽,維護火葬場)
  3. 正確的 RPC 調用姿勢是寫一個 DTO 進行傳輸,被調用方再根據 DTO 執行相應的操作
  4. 我們拒絕接受任何關於 RPC 傳輸 Wrapper 報錯相關的 issue 甚至 pr

4.2.3.1 AbstractWrapper

說明:QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父類
用於生成 sql 的 where 條件, entity 屬性也用於生成 sql 的 where 條件
注意: entity 生成的 where 條件與 使用各個 api 生成的 where 條件沒有任何關聯行爲

allEq

allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)

個別參數說明:

params : key爲數據庫字段名,value爲字段值
null2IsNull : 爲true則在mapvaluenull時調用 isNull 方法,爲false時則忽略valuenull

  • 例1: allEq({id:1,name:"老王",age:null})--->id = 1 and name = '老王' and age is null
  • 例2: allEq({id:1,name:"老王",age:null}, false)--->id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 

 個別參數說明:

filter : 過濾函數,是否允許字段傳入比對條件中
paramsnull2IsNull : 同上

  • 例1: allEq((k,v) -> k.indexOf("a") > 0, {id:1,name:"老王",age:null})--->name = '老王' and age is null
  • 例2: allEq((k,v) -> k.indexOf("a") > 0, {id:1,name:"老王",age:null}, false)--->name = '老王'

eq 等於 =

eq(R column, Object val)
eq(boolean condition, R column, Object val)

以下方法和上面eq方法的參數幾乎相同,僅寫出方法名稱參考,(between方法參數會多一個值)

  • ne 不等於<>
  • gt 大於 >
  • ge 大於等於 >=
  • lt 小於 <
  • le 小於大於 <=
  • between   BETWEEN 值1 AND 值2
  • notBetween   NOT BETWEEN 值1 AND 值2
  • like  LIKE '%值%'
  • notLike  NOT LIKE '%值%'
  • likeLeft  LIKE '%值'
  • likeRight  LIKE '值%'
  • isNull   字段 IS NULL
  • isNotNull   字段 IS NOT NULL
  • between BETWEEN   值1 AND 值2
  • notBetween NOT BETWEEN   值1 AND 值2
  • like  LIKE '%值%'
  • notLike  NOT LIKE '%值%'
  • likeLeft   LIKE '%值'
  • likeRight  LIKE '值%'

isNull、isNotNul  字段是否爲NULL

isNull(R column)
isNull(boolean condition, R column)

in、notIn

notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)

inSql、notInSql

inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
  • 字段 IN ( sql語句 )
  • 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
  • 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)

groupBy

groupBy(R... columns)
groupBy(boolean condition, R... columns)
  • 分組:GROUP BY 字段, ...
  • 例: groupBy("id", "name")--->group by id,name

orderByAsc、orderByDesc

orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
  • 排序:ORDER BY 字段, ... ASC/DESC
  • 例: orderByAsc("id", "name")--->order by id ASC,name ASC

orderBy

orderBy(boolean condition, boolean isAsc, R... columns)
  • 排序:ORDER BY 字段, ...
  • 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC

having

having(String sqlHaving, Object... params)
having(boolean condition, String sqlHaving, Object... params)
  • HAVING ( sql語句 )
  • 例: having("sum(age) > 10")--->having sum(age) > 10
  • 例: having("sum(age) > {0}", 11)--->having sum(age) > 11

or

or()
or(boolean condition)

注意事項:

主動調用or表示緊接着下一個方法不是用and連接!(不調用or則默認爲使用and連接)

and

and(Function<Param, Param> func)
and(boolean condition, Function<Param, Param> func)
  • AND 嵌套
  • 例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')

 nested

nested(Function<Param, Param> func)
nested(boolean condition, Function<Param, Param> func)
  • 正常嵌套 不帶 AND 或者 OR
  • 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')

apply

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
  • 拼接 sql

注意事項:

該方法可用於數據庫函數 動態入參的params對應前面applySql內部的{index}部分.這樣是不會有sql注入風險的,反之會有!

 

  • 例: apply("id = 1")--->id = 1
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

last 

last(String lastSql)
last(boolean condition, String lastSql)
  • 無視優化規則直接拼接到 sql 的最後

注意事項:

只能調用一次,多次調用以最後一次爲準 有sql注入的風險,請謹慎使用

  • 例: last("limit 1")

exists

exists(String existsSql)
exists(boolean condition, String existsSql)
  • 拼接 EXISTS ( sql語句 )
  • 例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)

notExists

notExists(String notExistsSql)
notExists(boolean condition, String notExistsSql)
  • 拼接 NOT EXISTS ( sql語句 )
  • 例: notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)

4.2.3.2 QueryWrapper

說明:

繼承自 AbstractWrapper ,自身的內部屬性 entity 也用於生成 where 條件
LambdaQueryWrapper, 可以通過 new QueryWrapper().lambda() 方法獲取

select

select(String... sqlSelect)
select(Predicate<TableFieldInfo> predicate)
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)
  • 設置查詢字段

說明:

以上方分法爲兩類.
第二類方法爲:過濾查詢字段(主鍵除外),入參不包含 class 的調用前需要wrapper內的entity屬性有值! 這兩類方法重複調用以最後一次爲準

  • 例: select("id", "name", "age")
  • 例: select(i -> i.getProperty().startsWith("test"))

UpdateWrapper

說明:

繼承自 AbstractWrapper ,自身的內部屬性 entity 也用於生成 where 條件
LambdaUpdateWrapper, 可以通過 new UpdateWrapper().lambda() 方法獲取!

set

set(String column, Object val)
set(boolean condition, String column, Object val)
  • SQL SET 字段
  • 例: set("name", "老李頭")
  • 例: set("name", "")--->數據庫字段值變爲空字符串
  • 例: set("name", null)--->數據庫字段值變爲null

setSql

setSql(String sql)
  • 設置 SET 部分 SQL
  • 例: setSql("name = '老李頭')

lambda

  • 獲取 LambdaWrapper
    QueryWrapper中是獲取LambdaQueryWrapper
    UpdateWrapper中是獲取LambdaUpdateWrapper

4.2.3.3 使用 Wrapper 自定義SQL

需求來源:

在使用了mybatis-plus之後, 自定義SQL的同時也想使用Wrapper的便利應該怎麼辦? 在mybatis-plus版本3.0.7得到了完美解決 版本需要大於或等於3.0.7, 以下兩種方案取其一即可

Service.java

mysqlMapper.getAll(Wrappers.<MysqlData>lambdaQuery().eq(MysqlData::getGroup, 1));

方案一 註解方式 Mapper.java

@Select("select * from mysql_data ${ew.customSqlSegment}")
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);

方案二 XML形式 Mapper.xml

<select id="getAll" resultType="MysqlData">
	SELECT * FROM mysql_data ${ew.customSqlSegment}
</select>

由於篇幅問題下面一節從MP的分頁插件開始

(完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章