<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4636字,需瀏覽 10分鐘

           ·

          2020-12-16 23:12

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

          一、MP 是什么

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

          1. 三大特性

          1)潤物無聲

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

          2)效率至上

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

          3)豐富功能

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

          2. 支持數(shù)據(jù)庫

          • mysql 、mariadb 、oracledb2 、h2hsql 、sqlitepostgresql 、sqlserver 、presto 、Gauss 、Firebird
          • Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、達夢數(shù)據(jù)庫 、虛谷數(shù)據(jù)庫 、人大金倉數(shù)據(jù)庫 、南大通用數(shù)據(jù)庫

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

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

          二、MP實戰(zhàn)

          1. 手摸手式項目練習

          1)數(shù)據(jù)庫及表準備

          sql 語句:

          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é)習,天天向上!');

          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)實體類

          @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)測試類

          @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é)習,天天向上!)
          **/

          小菜結(jié):

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

          2. ?CRUD 基操

          1)insert

          @Test
          public?void?insert()?{
          ????//這里使用了?lombok?中的建造者模式構(gòu)建對象
          ????User?user?=?User.builder().deptId(1).name("小華").remark("小華愛學(xué)習").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 默認的 ID生成策略,而是我們在實體類中指定的:

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

          我們既然已經(jīng)看到了 @TableId 這個注解,那我們再來關(guān)注一個常用注解 @TableField

          從注解名上我們就可以看出,@TableId 是用來標記主鍵 ID 的,而 @TableField 是用來標記其他字段的。

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

          • value

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

          • exist

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

          • condition

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

          • update

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

          • select

          用于是否查詢時約束,如果我們有個字段 remarktext 類型的,查詢的時候不想查詢該字段,那么就可以使用 @TableField(select = false) 來約束查詢的時候不查詢該字段

          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("小華愛玩游戲").build();
          ????userMapper.updateById(user);
          }
          /**?更新結(jié)果:
          User(id=3,?deptId=1,?name=小華,?remark=小華愛玩游戲)
          **/

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

          我們也可以將要更新的條件放進 user 對象 里面:

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

          3)delete

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

          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語句:
          DELETE?FROM?student?WHERE?id?=?3;
          **/

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

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

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

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

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

          4)select

          查詢操作在我們開發(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 個方法,我們接下來一個一個測試

          查詢所有
          @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é)習,天天向上!)
          ?SQL語句:
          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語句:
          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語句:
          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é)習,天天向上!)
          ?SQL語句:
          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語句:
          ?SELECT?id,?name,?dept_id,?remark?FROM?student?WHERE?(name?=?'小菜');
          **/

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

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

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

          如果我們沒有新建實體類進行結(jié)果封裝,我們還可以用 Map 來接收結(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é)習,天天向上!, id=2, dept_id=1}
          ?SQL語句:
          SELECT id, name, dept_id, remark FROM student WHERE (name LIKE '%小%');
          **/

          也可以用 Object 對象來接收結(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é)習,天天向上!, id=2, dept_id=1}
          ?SQL語句:
          SELECT id, name, dept_id, remark FROM student WHERE (name LIKE '%小%');
          **/

          分頁查詢
          @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("總頁數(shù):"?+?userIPage.getPages());
          ????System.out.println("當前頁:"?+?userIPage.getCurrent());
          ????System.out.println("頁大小:"?+?userIPage.getSize());
          ????userIPage.getRecords().forEach(System.out::println);
          }
          /**
          ?OUTPUT:
          數(shù)據(jù)總數(shù):2
          總頁數(shù):2
          當前頁:1
          頁大小:1
          User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
          ?SQL語句:
          ?SELECT?id,?name,?dept_id,?remark
          ?FROM?student
          ?WHERE?(name?LIKE?'%小%')
          ?LIMIT?0,1;
          **/

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

          CRUD 的基本操作中,我們想要通過條件查詢都是通過 Wrapper 類進行封裝的,上面只是簡單的用到 eqlike 操作。事實上這個類十分強大,我們在下面會詳細進行介紹。

          1)allEq

          全部 eq 或個別 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ù)說明:

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

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

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

          使用示例:

          • 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);?//會調(diào)用?isNull?方法
          ????userMapper.selectList(queryWrapper);
          }
          /**?
          ?結(jié)果:
          {}
          ?SQL語句:
          ?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);?//不會調(diào)用?isNull?方法
          ????userMapper.selectList(queryWrapper);
          }
          /**?
          ?結(jié)果:
          User(id=1, deptId=1, name=小菜, remark=關(guān)注小菜不迷路!)
          ?SQL語句:
          ?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);?//不會帶入條件進行查詢
          ????userMapper.selectList(queryWrapper);
          }
          /**?
          ?結(jié)果:
          {name=小菜, remark=關(guān)注小菜不迷路!, id=1, dept_id=1}
          {name=小明, remark=好好學(xué)習,天天向上!, id=2, dept_id=1}
          ?SQL語句:
          ?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”?才會用作條件判斷
          ????queryWrapper.allEq((k,?v)?->?(k.contains("m")),?params);
          ????userMapper.selectList(queryWrapper);
          }
          /**?
          ?結(jié)果:
          0
          ?SQL語句:
          ?SELECT?id,name,dept_id,remark
          ?FROM?student
          ?WHERE?(name?=?'小菜'?AND?remark?IS?NULL);
          ?**/

          2)比較操作

          • eq: 相當于 =
          • ne: 相當于 !=
          • gt: ?相當于 >
          • ge: 相當于>=
          • lt: ? 相當于 <
          • le: ? 相當于<=
          • between: ? 相當于between ... and ...
          • notBetween: ? 相當于not between ... and ...
          • in: ? 相當于in(.., .., ..)
          • notIn: ? 相當于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:

          拼接:主動調(diào)用 or 表示緊接著下一個方法不是用 and 連接!(不調(diào)用 or 則默認為使用 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查詢中,默認查詢所有的字段,如果有需要也可以通過select方法進行指定字段,如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 所對應(yīng)的 XML 的文件位置,我們在 通用 CRUD 中用到的 Mapper 是直接繼承 MP 提供的 BaseMapper ,我們也可以自定義方法,然后在 XML 文件中自定義 SQL,而這時我們需要告訴 Mapper 所對應(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 ?別名包掃描路徑,通過該屬性可以給包中的類注冊別名,注冊后在 Mapper 對應(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)進階配置

          • mapUnderScoreToCamelCase

          是否開啟自動駝峰命名規(guī)則映射,這個配置的默認值是 true,但是這個屬性在 MyBatis 中的默認值是 false,所以在我們平時的開發(fā)中都會將這個配置開啟。

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

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

          mybatis-plus.configuration.cache-enabled = false

          3)DB 策略配置

          • idType

          全局默認主鍵類型,設(shè)置后,即可省略實體對象中的@TableId(type = IdType.AUTO)配置。該配置的默認值為 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()配置。該配置的默認值為 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. 其他擴展

          1)自動填充

          有時候我們在插入或更新數(shù)據(jù)的時候,希望有些字段可以自動填充。比如我們平時數(shù)據(jù)表里面會有個 插入時間 或者 更新時間 這種字段,我們會默認以當前時間填充,在 MP 中我們也可以進行配置。

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

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

          其中自動填充的模式如下:

          public?enum?FieldFill?{
          ????/**
          ????*?默認不處理
          ????*/

          ????DEFAULT,
          ????/**
          ????*?插入時填充字段
          ????*/

          ????INSERT,
          ????/**
          ????*?更新時填充字段
          ????*/

          ????UPDATE,
          ????/**
          ????*?插入和更新時填充字段
          ????*/

          ????INSERT_UPDATE
          }

          然后我們再編寫自定義的填充處理模式:

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

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

          測試:

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

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

          2)邏輯刪除

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

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

          @TableLogic
          private?Integer?status;

          application.yaml 中配置:

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

          測試:

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

          可以看出這段 SQL 并沒有真正刪除,而是進行了邏輯刪除,只是更新了刪除標識

          3)通用枚舉

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

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

          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;
          ????}
          ????
          ????//注意要重寫此方法,不然會將值轉(zhuǎn)換成?‘MAN’,而不是?‘男’
          ????@Override
          ????public?String?toString()?{
          ????????return?this.value;
          ????}
          }

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

          private?SexEnum?sex;

          application.yaml 中配置:

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

          測試:

          @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語句:
          ?SELECT?id,sex,name,dept_id,remark,status
          ?FROM?student
          ?WHERE?status=1?AND?(name?=?'小菜');
          **/

          END

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

          看完不贊,都是壞蛋






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



          戳原文,獲取精選面試題!
          瀏覽 79
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    亚洲韩日在线 | 日本三级片天天干 | 国产激情片| 一级α片免费看刺激高潮视频 | 操婷婷视频在线观看网站 |