欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis-Plus3.x版本使用入門(mén)和踩過(guò)的坑

 更新時(shí)間:2023年10月16日 10:16:23   作者:Linn-cn  
Mybatis-Plus是Mybatis的增強(qiáng)版,他只是在Mybatis的基礎(chǔ)上增加了功能,且并未對(duì)原有功能進(jìn)行任何的改動(dòng),本文給大家說(shuō)一下MyBatis-Plus3.x版本使用入門(mén)和踩過(guò)的坑,感興趣的朋友跟隨小編一起看看吧

個(gè)人認(rèn)為呢,Mybatis-Plus是Mybatis的增強(qiáng)版,他只是在Mybatis的基礎(chǔ)上增加了功能,且并未對(duì)原有功能進(jìn)行任何的改動(dòng)??芍^是非常良心的一款開(kāi)源產(chǎn)品,今天我就來(lái)給大家簡(jiǎn)單的說(shuō)一下以下幾個(gè)功能和踩過(guò)的坑。

前言

對(duì)于看官網(wǎng)看不太懂的朋友,可以看下這個(gè)視頻,2.0倍速也可哦,https://www.imooc.com/learn/1171 慕課上的mybatis-plus的視頻。

2020/9/28 MybatisX 插件重新開(kāi)始更新并維護(hù)

MybatisX plugin Features:

  • mapper and xml can jump back and forth
  • mybatis.xml,mapper.xml prompt
  • mapper and xml support auto prompt like jpa (reference MybatisCodeHelperPro)
  • integrate mybatis generator Gui (copy from free mybatis plugin)

新版的MybatisX支持類(lèi)似JPA的Defining Query Methods 寫(xiě)法

2021/1/13 Mybatis-Plus 3.X版本代碼生成器模板

解決代碼生成器中Mybatis的xml文件生成兩遍的問(wèn)題,糾正之前的錯(cuò)誤寫(xiě)法。

mybatis-plus提供了非常強(qiáng)大的代碼生成器,可以一鍵生成controller、service、mapper、mapping文件,省去了很多重復(fù)的動(dòng)作,這里提供我簡(jiǎn)單封裝之后的代碼生成器的代碼

package edu.changda.milk.tea.order.service;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
 
/**
 * @classname: CodeGenerator
 * @description: mybatisplus代碼生成器
 * @author: Linn-cn@126.com
 **/
public class CodeGenerator {
 
    /**
     * 代碼生成器的配置常量
     */
    private static final String outPutDir = "輸出目錄";
    private static final String dataName = "root";
    private static final String dataPwd = "root";
    private static final String dataUrl = "jdbc:mysql://localhost:3306/數(shù)據(jù)庫(kù)名?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8";
    private static final String driverName = "com.mysql.cj.jdbc.Driver";
    private static final String parentPackage = "包名";
    private static final String mapperName = "dao";
    private static final String serviceName = "service";
    private static final String implName = "service.impl";
    private static final String pojoName = "entity";
    private static final String controllerName = "controller";
 
    private static final String projectPath = "項(xiàng)目主路徑";
 
    public static void main(String[] args) {
        // 代碼生成器
        AutoGenerator mpg = new AutoGenerator();
 
        // 全局配置
        GlobalConfig gc = getGlobalConfig();
        mpg.setGlobalConfig(gc);
 
        // 數(shù)據(jù)源配置
        DataSourceConfig dsc = getDataSourceConfig();
        mpg.setDataSource(dsc);
 
        // 包配置
        PackageConfig pc = getPackageConfig();
        mpg.setPackageInfo(pc);
 
        // 去掉默認(rèn)的mybatis的xml生成
        // 不設(shè)置的話會(huì)生成兩份xml
        mpg.setTemplate(new TemplateConfig().setXml(null));
 
        // 自定義xml生成路徑
        InjectionConfig cfg = getInjectionConfig();
        mpg.setCfg(cfg);
 
        // 策略配置
        StrategyConfig strategy = getStrategyConfig();
        mpg.setStrategy(strategy);
        mpg.execute();
    }
 
 
    /**
     * 全局配置
     *
     * @return
     */
    public static GlobalConfig getGlobalConfig() {
        return new GlobalConfig()
                .setOutputDir(projectPath)
                .setDateType(DateType.TIME_PACK)
                .setAuthor("Linn-cn")
                .setOpen(false)
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                // 覆蓋生成的文件
                .setFileOverride(true)
                .setServiceName("%sService");
    }
 
    /**
     * 數(shù)據(jù)源配置
     *
     * @return
     */
    public static DataSourceConfig getDataSourceConfig() {
        return new DataSourceConfig()
                .setUrl(dataUrl)
                .setDriverName(driverName)
                .setUsername(dataName)
                .setPassword(dataPwd);
    }
 
    /**
     * 包配置
     *
     * @return
     */
    public static PackageConfig getPackageConfig() {
        return new PackageConfig()
                .setParent(parentPackage)
                .setMapper(mapperName)
                .setEntity(pojoName)
                .setService(serviceName)
                .setController(controllerName)
                .setServiceImpl(implName)
                // 多模塊情況下,如果需要自定義生成路徑的話,案例如下,配置之后,上述配置全部失效
                .setPathInfo(new HashMap<String, String>(){{
                    put(ConstVal.CONTROLLER_PATH,
                            "絕對(duì)路徑");
                    put(ConstVal.ENTITY_PATH,
                            "絕對(duì)路徑");
                    put(ConstVal.SERVICE_PATH,
                            "絕對(duì)路徑");
                    put(ConstVal.SERVICE_IMPL_PATH,
                            "絕對(duì)路徑");
                    put(ConstVal.MAPPER_PATH,
                            "絕對(duì)路徑");
                }});
    }
 
    /**
     * 數(shù)據(jù)庫(kù)表配置
     *
     * @return
     */
    public static StrategyConfig getStrategyConfig() {
        return new StrategyConfig()
                .setNaming(NamingStrategy.underline_to_camel)
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setEntityTableFieldAnnotationEnable(true)
                .setEntityLombokModel(true)
                .setChainModel(true)
                .setEntityBooleanColumnRemoveIsPrefix(true)
                .setInclude(scanner("表名,多個(gè)英文逗號(hào)分割").split(","))
                // 默認(rèn)生成全部
                //.setExclude(null)
                .setTablePrefix("milk_tea_")
                .setControllerMappingHyphenStyle(true);
    }
 
    /**
     * 自定義xml文件生成路徑
     * 這里注意會(huì)生成兩個(gè)xml,一個(gè)是在你指定的下面,一個(gè)是在mapper包下的xml
     * 因?yàn)樵创a中的判斷,判斷的是tableInfo和pathInfo的xml屬性是否為null,這兩個(gè)類(lèi)都是默認(rèn)生成屬性的
     * 且對(duì)if (null != injectionConfig)自定義生成的判斷在默認(rèn)的前面,所以會(huì)生成兩遍。
     * 具體可見(jiàn)AbstractTemplateEngine batchOutput()的方法
     *
     * @return
     */
    public static InjectionConfig getInjectionConfig() {
        // 自定義配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() { }
        };
        String templatePath = "/templates/mapper.xml.vm";
        // 自定義輸出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定義配置會(huì)被優(yōu)先輸出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定義輸出文件名 , 如果你 Entity 設(shè)置了前后綴、此處注意 xml 的名稱(chēng)會(huì)跟著發(fā)生變化??!
                return projectPath + "/模塊路徑/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        return cfg;
    }
 
    /**
     * 讀取控制臺(tái)內(nèi)容
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("請(qǐng)輸入" + tip + ":");
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("請(qǐng)輸入正確的" + tip + "!");
    }
 
}

這里要注意,如上生成的實(shí)體類(lèi)是開(kāi)啟了lombox注解的,所以你如果用的idea的話,可能還要下載一個(gè)lombox插件和在pom.xml文件中導(dǎo)入lombox的包,不然木有效果,閑麻煩也可以關(guān)閉strategy.setEntityLombokModel(true);刪掉即可,默認(rèn)為false;

關(guān)于mybtais-plus3.x的分頁(yè)

我們知道m(xù)ybtais-plus3.x版本之前是自帶一個(gè)內(nèi)存分頁(yè)(在分頁(yè)的時(shí)候,是把所有的數(shù)據(jù)都查詢(xún)出來(lái),然后通過(guò)RowBounds進(jìn)行在內(nèi)存分頁(yè))的,也有分頁(yè)插件pagination。

但mybatis-plus3.x之前的分頁(yè)方法是這樣的,且返回的是List<T>集合,并且內(nèi)存分頁(yè)并不需要配置分頁(yè)插件

    /**
     * <p>
     * 根據(jù) entity 條件,查詢(xún)?nèi)坑涗洠ú⒎?yè))
     * </p>
     *
     * @param rowBounds 分頁(yè)查詢(xún)條件(可以為 RowBounds.DEFAULT)
     * @param wrapper   實(shí)體對(duì)象封裝操作類(lèi)(可以為 null)
     * @return List<T>
     */
    List<T> selectPage(RowBounds rowBounds, @Param("ew") Wrapper<T> wrapper);

但我使用mybtais-plus3.x之后的分頁(yè)是這樣的

    /**
     * 翻頁(yè)查詢(xún)
     *
     * @param page         翻頁(yè)對(duì)象
     * @param queryWrapper 實(shí)體對(duì)象封裝操作類(lèi) {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);

可以看到返回的是IPage接口,其實(shí)這里返回的IPage跟傳進(jìn)去的第一個(gè)參數(shù)page是一樣的,我們可以自己實(shí)現(xiàn)IPage接口也可以直接使用已經(jīng)提供

但這里要注意,3.x版本要使用分頁(yè),必須配置插件,否則會(huì)沒(méi)有效果,不像2.x沒(méi)配插件就是內(nèi)存分頁(yè)。

package com.jianghaichao.infantmom.config;
 
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
 
/**
 * @program: infantmom
 * @classname: MybatisPlusConfig
 * @description: mybatis-plus配置
 * @author: zhulin
 * @create: 2019-05-25 09:58
 **/
//Spring boot方式
@EnableTransactionManagement
@Configuration
@MapperScan("com.jianghaichao.infantmom.mapper")
public class MybatisPlusConfig {
 
    /**
     * 分頁(yè)插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 設(shè)置請(qǐng)求的頁(yè)面大于最大頁(yè)后操作, true調(diào)回到首頁(yè),false 繼續(xù)請(qǐng)求  默認(rèn)false
        // paginationInterceptor.setOverflow(false);
        // 設(shè)置最大單頁(yè)限制數(shù)量,默認(rèn) 500 條,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 開(kāi)啟 count 的 join 優(yōu)化,只針對(duì)部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

上面是springboot的配置形式

3.x版本的鏈?zhǔn)讲樵?xún)

MyBatis-Plus還提供了一種鏈?zhǔn)讲樵?xún)的方式,和上面的代碼效果一樣。
但是這種寫(xiě)法偏向于炫技,可讀性沒(méi)有上面的代碼強(qiáng),大家可以根據(jù)需要自行選擇方式。

List<BannerItem> bannerItems = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getBannerId, id)
                        .list();

如果只想查詢(xún)一條記錄,例如通過(guò)id查詢(xún)某條記錄的詳情,使用.one()即可,例如

BannerItem bannerItem = new LambdaQueryChainWrapper<>(bannerItemMapper)
                        .eq(BannerItem::getId, id)
                        .one();

2019/7/31 踩坑補(bǔ)充,mybatis-plus有關(guān)于時(shí)間問(wèn)題解決,例如查詢(xún)報(bào)錯(cuò)問(wèn)題

報(bào)錯(cuò)如下

org.springframework.dao.InvalidDataAccessApiUsageException: Error attempting to get column 'created' from result set.  Cause: java.sql.SQLFeatureNotSupportedException ; null; nested exception is java.sql.SQLFeatureNotSupportedException

解決方法:

在代碼生成器的全局策略中加上一行 gc.setDateType(DateType.ONLY_DATE);

設(shè)置生成的時(shí)間類(lèi)型為Date即可解決問(wèn)題,官網(wǎng)上也有這個(gè)問(wèn)題的介紹

2020/1/6 踩坑補(bǔ)充,mp的自動(dòng)填充

我們都知道,例如阿里開(kāi)發(fā)規(guī)范里面要求,每張表都要有create_time和update_time字段,所以我們?cè)诓迦霐?shù)據(jù)和修改數(shù)據(jù)的時(shí)候往往需要自己set值進(jìn)去,既然是一樣的操作,那么mp提供了自動(dòng)注入,這里寫(xiě)幾點(diǎn)自動(dòng)填充時(shí)需要注意的點(diǎn)。

1. 自動(dòng)注入在每次insert或update時(shí)都會(huì)觸發(fā),所以我們要考慮性能問(wèn)題,那么就會(huì)有如下優(yōu)化寫(xiě)法。這里只舉例insert的寫(xiě)法,具體看官網(wǎng)更為詳細(xì)(官網(wǎng)自行百度)

這里需要注意的一點(diǎn),這里的cretaeTime是實(shí)體類(lèi)屬性而不是數(shù)據(jù)庫(kù)字段名

且填充有如下條件:

補(bǔ)充,在3.3.0版本之后官方建議使用strictInsertFill方法,這里需要注意一定區(qū)分開(kāi)insert和update的區(qū)別

        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推薦使用)
        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 該方法有bug請(qǐng)升級(jí)到之后的版本如`3.3.1.8-SNAPSHOT`)
        /* 上面選其一使用,下面的已過(guò)時(shí)(注意 strictInsertFill 有多個(gè)方法,詳細(xì)查看源碼) */
        //this.setFieldValByName("operator", "Jerry", metaObject);
        //this.setInsertFieldValByName("operator", "Jerry", metaObject);

2020/1/9 踩坑補(bǔ)充,Wrapper 自定義SQL

最近使用mybatis-plus3.2.0版本碰到一個(gè)問(wèn)題,從官方文檔我們可看到3.0.7以后有了該功能

這里要提醒各位,如果在實(shí)例化的時(shí)候直接注入entity,你會(huì)發(fā)現(xiàn)無(wú)效,必須得用eq等方法

// 如下類(lèi)似寫(xiě)法均無(wú)效
LambdaQueryWrapper<WxCommentVO> wrapper = Wrappers.lambdaQuery(wxComment);
QueryWrapper<WxCommentVO> wrapper1 = new QueryWrapper<>(wxComment);
 
// 假如你需要判斷某字段值是否為1
wrapper.eq(WxComment::某字段,1);
 
必須得這樣寫(xiě),直接通過(guò)實(shí)體類(lèi)注入是無(wú)效的

2020/5/1字段類(lèi)型為 bit、tinyint(1) 時(shí)映射為 boolean 類(lèi)型

默認(rèn)mysql驅(qū)動(dòng)會(huì)把tinyint(1)字段映射為boolean: 0=false,非0=true

MyBatis 是不會(huì)自動(dòng)處理該映射,如果不想把tinyint(1)映射為boolean類(lèi)型:

  • 修改類(lèi)型tinyint(1)為tinyint(2)或者int
  • 需要修改請(qǐng)求連接添加參數(shù) tinyInt1isBit=false,如下:
jdbc:mysql://127.0.0.1:3306/mp?tinyInt1isBit=false

2020/9/28 數(shù)據(jù)庫(kù)關(guān)鍵字如何處理?

@TableField(value = "`status`")
private Boolean status;

2021/1/24 Map下劃線自動(dòng)轉(zhuǎn)駝峰 

@Bean
public ConfigurationCustomizer configurationCustomizer() {
    return i -> i.setObjectWrapperFactory(new MybatisMapWrapperFactory());
}

到此這篇關(guān)于MyBatis-Plus3.x版本使用入門(mén)和踩過(guò)的坑的文章就介紹到這了,更多相關(guān)MyBatis-Plus3.x入門(mén)使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot中@Autowired生效方式詳解

    SpringBoot中@Autowired生效方式詳解

    @Autowired注解可以用在類(lèi)屬性,構(gòu)造函數(shù),setter方法和函數(shù)參數(shù)上,該注解可以準(zhǔn)確地控制bean在何處如何自動(dòng)裝配的過(guò)程。在默認(rèn)情況下,該注解是類(lèi)型驅(qū)動(dòng)的注入
    2022-06-06
  • 詳解Java使用Pipeline對(duì)Redis批量讀寫(xiě)(hmset&hgetall)

    詳解Java使用Pipeline對(duì)Redis批量讀寫(xiě)(hmset&hgetall)

    本篇文章主要介紹了Java使用Pipeline對(duì)Redis批量讀寫(xiě)(hmset&hgetall),具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • JDK10中的局部變量類(lèi)型推斷var

    JDK10中的局部變量類(lèi)型推斷var

    這篇文章主要介紹了JDK10中的局部變量類(lèi)型推斷var,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 使用springboot訪問(wèn)圖片本地路徑并映射成url

    使用springboot訪問(wèn)圖片本地路徑并映射成url

    這篇文章主要介紹了使用springboot訪問(wèn)圖片本地路徑并映射成url的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java web中的servlet3 upload上傳文件實(shí)踐

    java web中的servlet3 upload上傳文件實(shí)踐

    這篇文章主要介紹了servlet3 upload上傳文件實(shí)踐,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-11-11
  • 詳解基于redis實(shí)現(xiàn)分布式鎖

    詳解基于redis實(shí)現(xiàn)分布式鎖

    系統(tǒng)的不斷擴(kuò)大,分布式鎖是最基本的保障。與單機(jī)的多線程不一樣的是,分布式跨多個(gè)機(jī)器。線程的共享變量無(wú)法跨機(jī)器。本文將介紹基于redis實(shí)現(xiàn)分布式鎖。
    2021-06-06
  • Java URL自定義私有網(wǎng)絡(luò)協(xié)議

    Java URL自定義私有網(wǎng)絡(luò)協(xié)議

    URI與URL的區(qū)別 一.先來(lái)序言一段 二.協(xié)議的自定義的理解 三.自定義協(xié)議與URL的關(guān)系 四.URL自定義私有協(xié)議實(shí)戰(zhàn) 五.后話,自定義mineType解析器
    2016-04-04
  • Java使用RedisTemplate操作Redis遇到的坑

    Java使用RedisTemplate操作Redis遇到的坑

    這篇文章主要介紹了Java使用RedisTemplate操作Redis遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring Boot中如何使用Swagger詳解

    Spring Boot中如何使用Swagger詳解

    Swagger是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful風(fēng)格的Web服務(wù),這篇文章主要給大家介紹了關(guān)于Spring Boot中如何使用Swagger的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Java并發(fā)編程中的ReentrantLock詳解

    Java并發(fā)編程中的ReentrantLock詳解

    這篇文章主要介紹了Java并發(fā)編程中的ReentrantLock詳解,從Java 5 開(kāi)始,引入了一個(gè)高級(jí)的處理并發(fā)的java.util.concurrent包,它提供了大量更高級(jí)的并發(fā)功能,能大大簡(jiǎn)化多線程程序的編寫(xiě),需要的朋友可以參考下
    2023-11-11

最新評(píng)論