1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        提高生產(chǎn)力,最全 MyBatis Plus 講解!

        共 4636字,需瀏覽 10分鐘

         ·

        2020-12-16 23:12

        如果你每天還在重復(fù)寫(xiě) CRUDSQL,如果你對(duì)這些 SQL 已經(jīng)不耐煩了,那么你何不花費(fèi)一些時(shí)間來(lái)閱讀這篇文章,然后對(duì)已有的老項(xiàng)目進(jìn)行改造,必有收獲!

        一、MP 是什么

        MP 全稱 Mybatis-Plus ,套用官方的解釋便是成為 MyBatis 最好的搭檔,簡(jiǎn)稱基友。它是在 MyBatis 的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā)、提高效率而生。

        1. 三大特性

        1)潤(rùn)物無(wú)聲

        只做增強(qiáng)不做改變,引入它不會(huì)對(duì)現(xiàn)有工程產(chǎn)生影響,如絲般順滑。

        2)效率至上

        只需簡(jiǎn)單配置,即可快速進(jìn)行單表 CRUD 操作,從而節(jié)省大量時(shí)間。

        3)豐富功能

        代碼生成、物理分頁(yè)、性能分析等功能一應(yīng)俱全。

        2. 支持?jǐn)?shù)據(jù)庫(kù)

        • mysql 、mariadboracle 、db2 、h2 、hsqlsqlite 、postgresql 、sqlserver 、presto 、Gauss 、Firebird
        • Phoenixclickhouse 、Sybase ASEOceanBase 、達(dá)夢(mèng)數(shù)據(jù)庫(kù) 、虛谷數(shù)據(jù)庫(kù) 、人大金倉(cāng)數(shù)據(jù)庫(kù) 、南大通用數(shù)據(jù)庫(kù)

        3. 框架結(jié)構(gòu)

        實(shí)話說(shuō),以上這些內(nèi)容只要你打開(kāi)官網(wǎng)也能看到,那么我們接下來(lái)就先來(lái)實(shí)際操作一番!

        二、MP實(shí)戰(zhàn)

        1. 手摸手式項(xiàng)目練習(xí)

        1)數(shù)據(jù)庫(kù)及表準(zhǔn)備

        sql 語(yǔ)句:

        use?test;
        CREATE?TABLE?`student`??(
        ??`id`?int(0)?NOT?NULL?AUTO_INCREMENT,
        ??`dept_id`?int(0)?NULL?DEFAULT?NULL,
        ??`name`?varchar(16)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_bin?NULL?DEFAULT?NULL,
        ??`remark`?varchar(32)?CHARACTER?SET?utf8mb4?COLLATE?utf8mb4_bin?NULL?DEFAULT?NULL,
        ??PRIMARY?KEY?(`id`)?USING?BTREE
        )?ENGINE?=?InnoDB?AUTO_INCREMENT?=?7?CHARACTER?SET?=?utf8mb4?COLLATE?=?utf8mb4_bin?ROW_FORMAT?=?Dynamic;
        --?----------------------------
        --?Records?of?student
        --?----------------------------
        INSERT?INTO?`student`?VALUES?(1,?1,?'小菜',?'關(guān)注小菜不迷路!');
        INSERT?INTO?`student`?VALUES?(2,?2,?'小明',?'好好學(xué)習(xí),天天向上!');

        2)pom 依賴

        <dependency>
        ????<groupId>org.springframework.bootgroupId>
        ????<artifactId>spring-boot-starter-testartifactId>
        dependency>

        <dependency>
        ????<groupId>org.projectlombokgroupId>
        ????<artifactId>lombokartifactId>
        ????<version>1.16.16version>
        dependency>

        <dependency>
        ????<groupId>com.baomidougroupId>
        ????<artifactId>mybatis-plus-boot-starterartifactId>
        ????<version>3.2.0version>
        dependency>

        <dependency>
        ????<groupId>mysqlgroupId>
        ????<artifactId>mysql-connector-javaartifactId>
        ????<version>8.0.21version>
        dependency>

        <dependency>
        ????<groupId>com.alibabagroupId>
        ????<artifactId>druidartifactId>
        ????<version>1.2.1version>
        dependency>

        <dependency>
        ????<groupId>junitgroupId>
        ????<artifactId>junitartifactId>
        ????<version>4.13.1version>
        dependency>

        3)配置文件

        spring:
        ??datasource:
        ????url:?jdbc:mysql://localhost:3306/test
        ????username:?root
        ????password:?123456
        ????driver-class-name:?com.mysql.cj.jdbc.Driver

        4)實(shí)體類

        @Data
        @Builder
        @TableName("student")
        public?class?User?{

        ????@TableId(type?=?IdType.AUTO)
        ????private?Integer?id;

        ????private?Integer?deptId;

        ????private?String?name;

        ????private?String?remark;
        }

        5)Mapper

        public?interface?UserMapper?extends?BaseMapper<User>?{}

        6)測(cè)試類

        @RunWith(SpringRunner.class)
        @SpringBootTest
        public?class?MapperTest?
        {

        ????@Autowired
        ????private?UserMapper?userMapper;

        ????@Test
        ????public?void?getAll()?{
        ????????List?users?=?userMapper.selectList(null);
        ????????users.forEach(System.out::println);
        ????}
        }
        /**?OUTPUT:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        User(id=2, deptId=1, name=小明, remark=好好學(xué)習(xí),天天向上!)
        **/

        小菜結(jié):

        在以上的結(jié)果,我們可以看到已經(jīng)打印出了數(shù)據(jù)庫(kù)中的全部數(shù)據(jù)(兩條)。而并沒(méi)有看到平時(shí)我們需要寫(xiě)的 mapper.xml 文件,只是用到了 usermapper 中的 selectList() 方法,而 UserMapper 繼承了 BaseMapper 這個(gè)接口,這個(gè)接口便是 MybatisPlus 提供給我們的,我們?cè)賮?lái)看下這個(gè)接口給我們提供了哪些方法。

        2. ?CRUD 基操

        1)insert

        @Test
        public?void?insert()?{
        ????//這里使用了?lombok?中的建造者模式構(gòu)建對(duì)象
        ????User?user?=?User.builder().deptId(1).name("小華").remark("小華愛(ài)學(xué)習(xí)").build();
        ????int?insertFlag?=?userMapper.insert(user);
        ????log.info("插入影響行數(shù),{}?|?小華的ID:?{}",?insertFlag,?user.getId());
        }
        /**?OUTPUT:
        插入影響行數(shù),1?|?小華的ID:?8
        **/

        可以看到我們不僅插入了數(shù)據(jù),而且還獲取到了插入數(shù)據(jù)的ID,但是值得注意的是這里的 ID 雖然是自增的,但并非是 MP 默認(rèn)的 ID生成策略,而是我們?cè)趯?shí)體類中指定的:

        MP 中支持的主鍵生成策略有以下幾種:

        我們既然已經(jīng)看到了 @TableId 這個(gè)注解,那我們?cè)賮?lái)關(guān)注一個(gè)常用注解 @TableField

        從注解名上我們就可以看出,@TableId 是用來(lái)標(biāo)記主鍵 ID 的,而 @TableField 是用來(lái)標(biāo)記其他字段的。

        可以看得出來(lái)這個(gè)注解中存在的值還是比較多的,下面介紹幾個(gè)常用的值:

        • value

        用于解決字段名不一致問(wèn)題和駝峰命名,比如實(shí)體類中屬性名為 remark,但是表中的字段名為 describe ,這個(gè)時(shí)候就可以使用 @TableField(value="describe") 來(lái)進(jìn)行轉(zhuǎn)換。駝峰轉(zhuǎn)換如果在全局中有配置駝峰命名,這個(gè)地方可不寫(xiě)。

        • exist

        用于在數(shù)據(jù)表中不存在的字段,我們可以使用 @TableField(exist = false) 來(lái)進(jìn)行標(biāo)記

        • condition

        用在預(yù)處理 WHERE 實(shí)體條件自定義運(yùn)算規(guī)則,比如我配置了 @TableField(condition = SqlCondition.LIKE),輸出 SQL 為:select 表 where name LIKE CONCAT('%',值,'%'),其中 SqlCondition 值如下:

        • update

        用在預(yù)處理 set 字段自定義注入,比如我配置了 @TableField(update = "%s+1"),其中 %s 會(huì)填充字段,輸出 SQL 為:update 表名 set 字段 = 字段+1 where 條件

        • select

        用于是否查詢時(shí)約束,如果我們有個(gè)字段 remarktext 類型的,查詢的時(shí)候不想查詢?cè)撟侄?,那么就可以使?@TableField(select = false) 來(lái)約束查詢的時(shí)候不查詢?cè)撟侄?/p>

        2)update

        MybatisPlus 的更新操作存在兩種:

        int?updateById(Param("et")?T?entity);

        int?update(@Param("et")?T?entity,?@Param("ew")?Wrapper?updateWrapper);
        根據(jù) ID 更新
        @Test
        public?void?update()?{
        ????User?user?=?User.builder().id(3).name("小華").remark("小華愛(ài)玩游戲").build();
        ????userMapper.updateById(user);
        }
        /**?更新結(jié)果:
        User(id=3,?deptId=1,?name=小華,?remark=小華愛(ài)玩游戲)
        **/

        根據(jù)條件更新
        @Test
        public?void?update()?{
        ????UpdateWrapper?updateWrapper?=?new?UpdateWrapper<>();
        ????updateWrapper.eq("name","小華").set("remark","小華愛(ài)下棋");
        ????userMapper.update(null,?updateWrapper);
        }
        /**?更新結(jié)果:
        User(id=3,?deptId=1,?name=小華,?remark=小華愛(ài)下棋)
        **/

        我們也可以將要更新的條件放進(jìn) user 對(duì)象 里面:

        @Test
        public?void?update()?{
        ????UpdateWrapper?updateWrapper?=?new?UpdateWrapper<>();
        ????updateWrapper.eq("name","小華");
        ????User?user?=?User.builder().remark("小華愛(ài)游泳").build();
        ????userMapper.update(user,?updateWrapper);
        }
        /**?更新結(jié)果:
        User(id=3,?deptId=1,?name=小華,?remark=小華愛(ài)游泳)
        **/

        3)delete

        MybatisPlus 中刪除的方式相對(duì)于更新多,總共有四種:

        int?deleteById(Serializable?id);

        int?deleteByMap(@Param("cm")?Map?columnMap);

        int?delete(@Param("ew")?Wrapper?wrapper);

        int?deleteBatchIds(@Param("coll")?Collection?idList);
        根據(jù) ID 刪除
        @Test
        public?void?deleteById()?{
        ????userMapper.deleteById(3);
        }
        /** SQL語(yǔ)句:
        DELETE?FROM?student?WHERE?id?=?3;
        **/

        根據(jù) Map 刪除
        @Test
        public?void?deleteByMap()?{
        ????HashMap?columnMap?=?new?HashMap<>();
        ????columnMap.put("name","小華");
        ????columnMap.put("remark","小華愛(ài)游泳");
        ????userMapper.deleteByMap(columnMap);
        }
        /** SQL語(yǔ)句:
        DELETE?FROM?student?WHRE?name?=?'小華'?AND?remark?=?'小華愛(ài)游泳';
        **/

        根據(jù) Wrapper 刪除
        @Test
        public?void?delete()?{
        ????UpdateWrapper?wrapper?=?new?UpdateWrapper<>();
        ????wrapper.eq("remark","小華愛(ài)下棋");
        ????userMapper.delete(wrapper);
        }
        /** SQL語(yǔ)句:
        DELETE?FROM?student?WHRE?remark?=?'小華愛(ài)下棋';
        **/

        根據(jù) Wrapper 刪除還有另外一種方式,直接將實(shí)體類放入 Wrapper 中包裝:

        @Test
        public?void?delete()?{
        ????User?user?=?User.builder().remark("小華愛(ài)下棋").build();
        ????UpdateWrapper?wrapper?=?new?UpdateWrapper<>(user);
        ????userMapper.delete(wrapper);
        }
        /** SQL語(yǔ)句:
        DELETE?FROM?student?WHRE?remark?=?'小華愛(ài)下棋';
        **/

        根據(jù) ID 批量刪除
        @Test
        public?void?deleteBatchIds()?{
        ????List?idList?=?new?ArrayList<>();
        ????idList.add(4);
        ????idList.add(7);
        ????userMapper.deleteBatchIds(idList);
        }
        /** SQL語(yǔ)句:
        DELETE?FROM?student?WHERE?id?In?(4,7)
        **/

        4)select

        查詢操作在我們開(kāi)發(fā)中是最經(jīng)常用到的,也是重中之重。MybatisPlus 中支持查詢的方法也比較多,如下:

        T?selectById(Serializable?id);

        List?selectBatchIds(@Param("coll")?Collection?idList);

        List?selectByMap(@Param("cm")?Map?columnMap);

        T?selectOne(@Param("ew")?Wrapper?queryWrapper);

        Integer?selectCount(@Param("ew")?Wrapper?queryWrapper);

        List?selectList(@Param("ew")?Wrapper?queryWrapper);

        List>?selectMaps(@Param("ew")?Wrapper?queryWrapper);

        List?selectObjs(@aram("ew")?Wrapper?queryWrapper);

        IPage?selectPage(IPage?page,?@Param("ew")?Wrapper?queryWrapper);

        IPage>?selectMapsPage(IPage?page,?@Param("ew")?Wrapper?queryWrapper);

        可以看到總共有 10 個(gè)方法,我們接下來(lái)一個(gè)一個(gè)測(cè)試

        查詢所有
        @Test
        public?void?selectList()?{
        ????List?users?=?userMapper.selectList(null);
        ????users.forEach(System.out::println);
        }
        /**?
        ?OUTPUT:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        User(id=2, deptId=1, name=小明, remark=好好學(xué)習(xí),天天向上!)
        ?SQL語(yǔ)句:
        SELECT?id,?dept_id,?name,?remark?FROM?student;
        **/

        查詢數(shù)量
        @Test
        public?void?selectCount()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.like("name","小");
        ????System.out.println(userMapper.selectCount(queryWrapper));
        }
        /**?
        ?OUTPUT:
        2
        ?SQL語(yǔ)句:
        SELECT?COUNT(?1?)?FROM?student?WHERE?(name?LIKE?'%小%');
        **/

        根據(jù) ID 查詢
        @Test
        public?void?selectById()?{
        ????User?user?=?userMapper.selectById(1);
        ????System.out.println(user);
        }
        /**?
        ?OUTPUT:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        ?SQL語(yǔ)句:
        SELECT?id,?dept_id,?name,?remark?FROM?student?WHERE?ID?=?1;
        **/

        根據(jù) ID 批量查詢
        @Test
        public?void?selectBatchIds()?{
        ????List?users?=?userMapper.selectBatchIds(Arrays.asList(1,?2));
        ????users.forEach(System.out::println);
        }
        /**?
        ?OUTPUT:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        User(id=2, deptId=1, name=小明, remark=好好學(xué)習(xí),天天向上!)
        ?SQL語(yǔ)句:
        SELECT?id,?dept_id,?name,?remark?FROM?student?WHERE?ID?IN?(1,?2);
        **/

        根據(jù)條件查詢單條
        @Test
        public?void?selectOne()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.eq("name","小菜");
        ????User?user?=?userMapper.selectOne(queryWrapper);
        ????System.out.println(user);
        }
        /**
        ?OUTPUT:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        ?SQL語(yǔ)句:
        ?SELECT?id,?name,?dept_id,?remark?FROM?student?WHERE?(name?=?'小菜');
        **/

        根據(jù)條件查詢多條

        通過(guò) map 傳遞參數(shù),不是通過(guò) LIKE 查詢,而是通過(guò) = 查詢

        @Test
        public?void?selectByMap()?{
        ????HashMap?columnMap?=?new?HashMap<>();
        ????columnMap.put("name","小");
        ????List?users?=?userMapper.selectByMap(columnMap);
        ????users.forEach(System.out::println);
        }
        /**
        ?OUTPUT:
        null
        ?SQL語(yǔ)句:
        SELECT?id,?name,?dept_id,?remark?FROM?student?WHERE?name?=?'小';
        **/

        如果我們沒(méi)有新建實(shí)體類進(jìn)行結(jié)果封裝,我們還可以用 Map 來(lái)接收結(jié)果集:

        @Test
        public?void?selectMaps()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.like("name","小");
        ????List>?maps?=?userMapper.selectMaps(queryWrapper);
        ????maps.forEach(System.out::println);
        }
        /**
        ?OUTPUT:
        {name=小菜, remark=關(guān)注小菜不迷路!, id=1, dept_id=1}
        {name=小明, remark=好好學(xué)習(xí),天天向上!, id=2, dept_id=1}
        ?SQL語(yǔ)句:
        SELECT id, name, dept_id, remark FROM student WHERE (name LIKE '%小%');
        **/

        也可以用 Object 對(duì)象來(lái)接收結(jié)果集:

        @Test
        public?void?selectObjs()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.like("name",?"小");
        ????List?objects?=?userMapper.selectObjs(queryWrapper);
        }
        /**
        ?OUTPUT:
        {name=小菜, remark=關(guān)注小菜不迷路!, id=1, dept_id=1}
        {name=小明, remark=好好學(xué)習(xí),天天向上!, id=2, dept_id=1}
        ?SQL語(yǔ)句:
        SELECT id, name, dept_id, remark FROM student WHERE (name LIKE '%小%');
        **/

        分頁(yè)查詢
        @Test
        public?void?selectPage()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.like("name",?"小");
        ????Page?page?=?new?Page<>(1,?1);
        ????IPage?userIPage?=?userMapper.selectPage(page,?queryWrapper);
        ????System.out.println("數(shù)據(jù)總數(shù):"?+?userIPage.getTotal());
        ????System.out.println("總頁(yè)數(shù):"?+?userIPage.getPages());
        ????System.out.println("當(dāng)前頁(yè):"?+?userIPage.getCurrent());
        ????System.out.println("頁(yè)大小:"?+?userIPage.getSize());
        ????userIPage.getRecords().forEach(System.out::println);
        }
        /**
        ?OUTPUT:
        數(shù)據(jù)總數(shù):2
        總頁(yè)數(shù):2
        當(dāng)前頁(yè):1
        頁(yè)大小:1
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        ?SQL語(yǔ)句:
        ?SELECT?id,?name,?dept_id,?remark
        ?FROM?student
        ?WHERE?(name?LIKE?'%小%')
        ?LIMIT?0,1;
        **/

        3. 條件構(gòu)造器

        CRUD 的基本操作中,我們想要通過(guò)條件查詢都是通過(guò) Wrapper 類進(jìn)行封裝的,上面只是簡(jiǎn)單的用到 eqlike 操作。事實(shí)上這個(gè)類十分強(qiáng)大,我們?cè)谙旅鏁?huì)詳細(xì)進(jìn)行介紹。

        1)allEq

        全部 eq 或個(gè)別 isNull

        allEq(Map?params)
        allEq(Map?params,?boolean?null2IsNull)
        allEq(boolean?condition,?Map?params,?boolean?null2IsNull)
        ????
        allEq(BiPredicate?filter,?Map?params)
        allEq(BiPredicate?filter,?Map?params,?boolean?null2IsNull)
        allEq(boolean?condition,?BiPredicate?filter,?Map?params,?boolean?null2IsNull)?

        參數(shù)說(shuō)明:

        param: key 為數(shù)據(jù)庫(kù)字段名,value 為字段值

        **nullsIsNull:**為 true 則在 map 的 value 為 null 時(shí)調(diào)用 isNull 方法,為 false 時(shí)則忽略 value 為 null 時(shí)不調(diào)用 isNull 方法

        filter: 過(guò)濾函數(shù),判斷是否允許字段傳入比對(duì)條件中

        使用示例:

        • allEq(Map params)
        @Test
        public?void?testAllEq()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????Map?params?=?new?HashMap<>();
        ????params.put("name","小菜");
        ????params.put("dept_id",1);
        ????params.put("remark",null);
        ????queryWrapper.allEq(params);?//會(huì)調(diào)用?isNull?方法
        ????userMapper.selectList(queryWrapper);
        }
        /**?
        ?結(jié)果:
        {}
        ?SQL語(yǔ)句:
        ?SELECT?id,name,dept_id,remark
        ?FROM?student
        ?WHERE?(name?=?'小菜'?AND?dept_id?=?1?AND?remark?IS?NULL);
        ?**/

        • allEq(Map params, boolean null2IsNull)
        @Test
        public?void?testAllEq()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????Map?params?=?new?HashMap<>();
        ????params.put("name","小菜");
        ????params.put("dept_id",1);
        ????params.put("remark",null);
        ????queryWrapper.allEq(params,?false);?//不會(huì)調(diào)用?isNull?方法
        ????userMapper.selectList(queryWrapper);
        }
        /**?
        ?結(jié)果:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
        ?SQL語(yǔ)句:
        ?SELECT?id,name,dept_id,remark
        ?FROM?student
        ?WHERE?(name?=?'小菜'?AND?dept_id?=?1);
        ?**/

        • allEq(boolean condition, Map params, boolean null2IsNull)
        @Test
        public?void?testAllEq()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????Map?params?=?new?HashMap<>();
        ????params.put("name","小菜");
        ????params.put("dept_id",1);
        ????params.put("remark",null);
        ????queryWrapper.allEq(false,params,false);?//不會(huì)帶入條件進(jìn)行查詢
        ????userMapper.selectList(queryWrapper);
        }
        /**?
        ?結(jié)果:
        {name=小菜, remark=關(guān)注小菜不迷路!, id=1, dept_id=1}
        {name=小明, remark=好好學(xué)習(xí),天天向上!, id=2, dept_id=1}
        ?SQL語(yǔ)句:
        ?SELECT?id,name,dept_id,remark
        ?FROM?student;
        ?**/

        • allEq(BiPredicate filter, Map params)
        @Test
        public?void?testAllEq()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????Map?params?=?new?HashMap<>();
        ????params.put("name",?"小菜");
        ????params.put("dept_id",?1);
        ????params.put("remark",?null);
        ????//只有?key?中含有?“m”?才會(huì)用作條件判斷
        ????queryWrapper.allEq((k,?v)?->?(k.contains("m")),?params);
        ????userMapper.selectList(queryWrapper);
        }
        /**?
        ?結(jié)果:
        0
        ?SQL語(yǔ)句:
        ?SELECT?id,name,dept_id,remark
        ?FROM?student
        ?WHERE?(name?=?'小菜'?AND?remark?IS?NULL);
        ?**/

        2)比較操作

        • eq: 相當(dāng)于 =
        • ne: 相當(dāng)于 !=
        • gt: ?相當(dāng)于 >
        • ge: 相當(dāng)于>=
        • lt: ? 相當(dāng)于 <
        • le: ? 相當(dāng)于<=
        • between: ? 相當(dāng)于between ... and ...
        • notBetween: ? 相當(dāng)于not between ... and ...
        • in: ? 相當(dāng)于in(.., .., ..)
        • notIn: ? 相當(dāng)于not in(.., .., ..)

        3)模糊查詢

        • like: like("name","小菜") --> name like "%小菜%"
        • notLike: notLike("name","小菜") --> name not like "%小菜%"
        • likeLeft: ?like("name","小菜") --> name like "%小菜"
        • likeRight: like("name","小菜") --> name like "小菜%"

        4)排序

        • orderBy:
        orderBy(boolean?condition,?boolean?isAsc,?R...?columns)

        orderBy(true, true, "id", "name") --> order by id ASC, name ASC

        • orderByAsc:

        orderByAsc("id","name") --> order by id ASC, name ASC

        • orderByDesc:

        orderByDesc("id","name) --> order by id Desc, name Desc

        5)邏輯查詢

        • or:

        拼接:主動(dòng)調(diào)用 or 表示緊接著下一個(gè)方法不是用 and 連接!(不調(diào)用 or 則默認(rèn)為使用 and 連接), eq("id",1).or().eq("name","老王")

        嵌套:or(i -> i.eq("name", "李白").ne("status", "活著"))

        • and:

        嵌套:and(i -> i.eq("name", "李白").ne("status", "活著"))

        6)select

        在MP查詢中,默認(rèn)查詢所有的字段,如果有需要也可以通過(guò)select方法進(jìn)行指定字段,如select("id", "name")

        4. 配置講解

        1)基本配置

        • configLocation

        用于指明 **MyBatis ** 配置文件的位置,如果我們有 MyBatis 的配置文件,需將配置文件的路徑配置到 configLocation

        SpringBoot:

        mybatis-plus.config-location = classpath:mybatis-config.xml

        SpringMvc:

        <bean?id="sqlSessionFactory"
        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

        <property?name="configLocation"?value="classpath:mybatis-config.xml"/>
        bean
        • mapperLocations

        用于指明 Mapper 所對(duì)應(yīng)的 XML 的文件位置,我們?cè)?通用 CRUD 中用到的 Mapper 是直接繼承 MP 提供的 BaseMapper ,我們也可以自定義方法,然后在 XML 文件中自定義 SQL,而這時(shí)我們需要告訴 Mapper 所對(duì)應(yīng) XML 文件的位置

        SpringBoot:

        mybatis-plus.mapper-locations = classpath*:mybatis/*.xml

        SpringMVC:

        <bean?id="sqlSessionFactory"
        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

        <property?name="mapperLocations"?value="classpath*:mybatis/*.xml"/>
        bean>
        • typeAliasesPackage

        用于 MyBatis ?別名包掃描路徑,通過(guò)該屬性可以給包中的類注冊(cè)別名,注冊(cè)后在 Mapper 對(duì)應(yīng)的 XML 文件中可以直接使用類名,而不用使用全限定的類名

        SpringBoot:

        mybatis-plus.type-aliases-package = cbuc.life.bean

        SpringMVC:

        <bean?id="sqlSessionFactory"
        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

        <property?name="typeAliasesPackage"
        value="com.baomidou.mybatisplus.samples.quickstart.entity"/>

        bean>

        2)進(jìn)階配置

        • mapUnderScoreToCamelCase

        是否開(kāi)啟自動(dòng)駝峰命名規(guī)則映射,這個(gè)配置的默認(rèn)值是 true,但是這個(gè)屬性在 MyBatis 中的默認(rèn)值是 false,所以在我們平時(shí)的開(kāi)發(fā)中都會(huì)將這個(gè)配置開(kāi)啟。

        #關(guān)閉自動(dòng)駝峰映射,該參數(shù)不能和mybatis-plus.config-location同時(shí)存在
        mybatis-plus.configuration.map-underscore-to-camel-case = false
        • cacheEnabled

        全局地開(kāi)啟或關(guān)閉配置文件中的所有映射器已經(jīng)配置的任何緩存,默認(rèn)為 true。

        mybatis-plus.configuration.cache-enabled = false

        3)DB 策略配置

        • idType

        全局默認(rèn)主鍵類型,設(shè)置后,即可省略實(shí)體對(duì)象中的@TableId(type = IdType.AUTO)配置。該配置的默認(rèn)值為 ID_WORKER

        SpringBoot:

        mybatis-plus.global-config.db-config.id-type = auto

        SpringMVC:

        <bean?id="sqlSessionFactory"
        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

        ?<property?name="dataSource"?ref="dataSource"/>
        ????<property?name="globalConfig">
        ????????<bean?class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        ????????????<property?name="dbConfig">
        ????????????????<bean?????????class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
        ?????????????????<property?name="idType"?value="AUTO"/>
        ????????????????bean>
        ????????????property>
        ????????bean>
        ????property>
        bean>
        • tablePrefix

        表名前綴,全局配置后可省略@TableName()配置。該配置的默認(rèn)值為 null

        SpringBoot:

        mybatis-plus.global-config.db-config.table-prefix = yq_

        SpringMVC:

        <bean?id="sqlSessionFactory"
        class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">

        ????<property?name="dataSource"?ref="dataSource"/>
        ????<property?name="globalConfig">
        ????????<bean?class="com.baomidou.mybatisplus.core.config.GlobalConfig">
        ????????????<property?name="dbConfig">
        ????????????????<bean????????????class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
        ?????????????????<property?name="idType"?value="AUTO"/>
        ?????????????????<property?name="tablePrefix"?value="yq_"/>
        ????????????????bean>
        ????????????property>
        ????????bean>
        ????property>
        bean>

        5. 其他擴(kuò)展

        1)自動(dòng)填充

        有時(shí)候我們?cè)诓迦牖蚋聰?shù)據(jù)的時(shí)候,希望有些字段可以自動(dòng)填充。比如我們平時(shí)數(shù)據(jù)表里面會(huì)有個(gè) 插入時(shí)間 或者 更新時(shí)間 這種字段,我們會(huì)默認(rèn)以當(dāng)前時(shí)間填充,在 MP 中我們也可以進(jìn)行配置。

        首先我們需要借助 @TableField(fill = FieldFill.INSERT) 這個(gè)注解,在插入時(shí)進(jìn)行填充。

        @TableField(fill?=?FieldFill.INSERT)
        private?String?remark;

        其中自動(dòng)填充的模式如下:

        public?enum?FieldFill?{
        ????/**
        ????*?默認(rèn)不處理
        ????*/

        ????DEFAULT,
        ????/**
        ????*?插入時(shí)填充字段
        ????*/

        ????INSERT,
        ????/**
        ????*?更新時(shí)填充字段
        ????*/

        ????UPDATE,
        ????/**
        ????*?插入和更新時(shí)填充字段
        ????*/

        ????INSERT_UPDATE
        }

        然后我們?cè)倬帉?xiě)自定義的填充處理模式:

        @Component
        public?class?MyMetaObjectHandler?implements?MetaObjectHandler?{
        ????@Override
        ????public?void?insertFill(MetaObject?metaObject)?{
        ????????Object?remark?=?getFieldValByName("remark",?metaObject);
        ????????if?(null?==?remark)?{
        ????????????setFieldValByName("remark",?"好好學(xué)習(xí)",?metaObject);
        ????????}
        ????}

        ????@Override
        ????public?void?updateFill(MetaObject?metaObject)?{
        ??//自定義更新時(shí)填充
        ????}
        }

        測(cè)試:

        @Test
        public?void?testObjectHandler()?{
        ????User?user?=?User.builder().deptId(1).name("小明").build();
        ????userMapper.insert(user);
        }
        /**
        ?SQL語(yǔ)句:
        INSERT?INTO?student?(?name,?dept_id,?remark?)
        VALUES?(?'小明',?1,?'好好學(xué)習(xí)'?);
        **/

        可以看到插入時(shí),已經(jīng)自動(dòng)將我們填充的字段合并進(jìn)去。

        2)邏輯刪除

        在開(kāi)發(fā)中,很多時(shí)候我們刪除數(shù)據(jù)并不需要真正意義上的物理刪除,而是使用邏輯刪除,這樣子查詢的時(shí)候需要狀態(tài)條件,確保被標(biāo)記的數(shù)據(jù)不被查詢到。MP 當(dāng)然也支持這樣的功能。

        我們需要先為 student 表添加一個(gè)字段 status 來(lái)聲明數(shù)據(jù)是否被刪除,0 表示被刪除,1表示未刪除,然后也需要在實(shí)體類上增加這個(gè)屬性:

        @TableLogic
        private?Integer?status;

        application.yaml 中配置:

        mybatis-plus:
        ??global-config:
        ????db-config:
        ??????logic-delete-value:?0
        ??????logic-not-delete-value:?1

        測(cè)試:

        @Test
        public?void?testLogicDelete()?{
        ????userMapper.deleteById(1);
        }
        /**
        ?SQL語(yǔ)句:
        UPDATE?student?SET?status=0
        WHERE?id=1?AND?status=1;
        **/

        可以看出這段 SQL 并沒(méi)有真正刪除,而是進(jìn)行了邏輯刪除,只是更新了刪除標(biāo)識(shí)

        3)通用枚舉

        如果有性別之類的字段,我們通常會(huì)用 01 來(lái)表示,但是查出來(lái)我們得進(jìn)行值轉(zhuǎn)換,這個(gè)時(shí)候我們就可以使用枚舉來(lái)解決這個(gè)問(wèn)題:

        首先為 student 表添加一個(gè) sex 字段來(lái)表示性別,0 表示女性,1 表示男性,然后定義一個(gè)枚舉類:

        public?enum?SexEnum?implements?IEnum?{
        ????MAN(1,?"男"),
        ????WOMEN(0,?"女");

        ????private?int?code;

        ????private?String?value;

        ????SexEnum(int?code,?String?value)?{
        ????????this.code?=?code;
        ????????this.value?=?value;
        ????}

        ????@Override
        ????public?Integer?getValue()?{
        ????????return?this.code;
        ????}
        ????
        ????//注意要重寫(xiě)此方法,不然會(huì)將值轉(zhuǎn)換成?‘MAN’,而不是?‘男’
        ????@Override
        ????public?String?toString()?{
        ????????return?this.value;
        ????}
        }

        然后在實(shí)體類中添加對(duì)應(yīng)屬性:

        private?SexEnum?sex;

        application.yaml 中配置:

        mybatis-plus:
        ??type-enums-package:?cbuc.life.enums

        測(cè)試:

        @Test
        public?void?selectOne()?{
        ????QueryWrapper?queryWrapper?=?new?QueryWrapper<>();
        ????queryWrapper.eq("name",?"小菜");
        ????User?user?=?userMapper.selectOne(queryWrapper);
        ????System.out.println(user);
        }
        /**
        ?輸出結(jié)果:
        User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!, status=1, sex=男)
        ?SQL語(yǔ)句:
        ?SELECT?id,sex,name,dept_id,remark,status
        ?FROM?student
        ?WHERE?status=1?AND?(name?=?'小菜');
        **/

        END

        這篇文章寫(xiě)到這里就告一段落了哦,內(nèi)容有點(diǎn)長(zhǎng),不過(guò)如果能完整看下來(lái),我相信你肯定能夠很好的使用 MybatisPlus 啦!路漫漫,小菜與你一同求索!

        看完不贊,都是壞蛋






        關(guān)注Java技術(shù)??锤喔韶?/strong>



        戳原文,獲取精選面試題!
        瀏覽 79
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

          <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产奶头好大揉着好爽视频 | www.色天堂 | 97香蕉成人嫩草 | 国产又粗又大又爽 | 思思热在线观看视频 | 国产一区在线视频播放 | 一级黄色免费看 | 女厕又白又嫩的大屁股 | 黄色一级A | 色婷婷综合久久久中文字幕 |