<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>

          Mybatis-plus常用API全套教程,看完沒有不懂的

          共 11542字,需瀏覽 24分鐘

           ·

          2021-01-19 16:33


          作者:java架構(gòu)師阿松

          www.toutiao.com/i6869621037831717387

          前言

          官網(wǎng):

          https://baomidou.com/

          創(chuàng)建數(shù)據(jù)庫(kù)

          數(shù)據(jù)庫(kù)名為mybatis_plus

          創(chuàng)建表

          創(chuàng)建user表

          DROP?TABLE?IF?EXISTS?user;
          CREATE?TABLE?user
          (
          id?BIGINT(20)?NOT?NULL?COMMENT?'主鍵ID',
          name?VARCHAR(30)?NULL?DEFAULT?NULL?COMMENT?'姓名',
          age?INT(11)?NULL?DEFAULT?NULL?COMMENT?'年齡',
          email?VARCHAR(50)?NULL?DEFAULT?NULL?COMMENT?'郵箱',
          PRIMARY?KEY?(id)
          );
          INSERT?INTO?user?(id,?name,?age,?email)?VALUES
          (1,?'Jone',?18,?'[email protected]'),
          (2,?'Jack',?20,?'[email protected]'),
          (3,?'Tom',?28,?'[email protected]'),
          (4,?'Sandy',?21,?'[email protected]'),
          (5,?'Billie',?24,?'[email protected]');

          注意:-- 真實(shí)開發(fā)中往往都會(huì)有這四個(gè)字段,version(樂觀鎖)、deleted(邏輯刪除)、gmt_create(創(chuàng)建時(shí)間)、gmt_modified(修改時(shí)間)

          初始化項(xiàng)目

          使用SpringBoot器?初始化!

          導(dǎo)入依賴


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

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


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

          注意:盡量不要同時(shí)導(dǎo)入 mybatis 和 mybatis-plus!避免版本的差異造成無法預(yù)知的問題。

          連接數(shù)據(jù)庫(kù)

          創(chuàng)建application.yml

          spring:
          ??profiles:
          ????active:?dev
          ??datasource:
          #?驅(qū)動(dòng)不同?mysql?5??com.mysql.jdbc.Driver
          #?????????mysql?8??com.mysql.cj.jdbc.Driver、需要增加時(shí)區(qū)的配置serverTimezone=GMT%2B8
          ????url:?jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
          ????driver-class-name:?com.mysql.cj.jdbc.Driver
          ????username:?root
          ????password:?root

          業(yè)務(wù)代碼

          實(shí)體類

          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public?class?User?{
          ??private?Long?id;
          ??private?String?name;
          ??private?Integer?age;
          ??private?String?email;
          }?

          mapper接口

          import?com.baomidou.mybatisplus.core.mapper.BaseMapper;
          import?com.kuang.pojo.User;
          import?org.springframework.stereotype.Repository;
          //?在對(duì)應(yīng)的Mapper上面繼承基本的類?BaseMapper
          @Repository?//?代表持久層
          public?interface?UserMapper?extends?BaseMapper<User>?{
          ??//?所有的CRUD操作都已經(jīng)編寫完成了
          }

          注意點(diǎn),我們需要在主啟動(dòng)類上去掃描我們的mapper包下的所有接口 @MapperScan(“com.kwhua.mapper”)

          測(cè)試

          @SpringBootTest
          class?MybatisPlusApplicationTests?{
          ??//?繼承了BaseMapper,所有的方法都來自己父類
          ??//?我們也可以編寫自己的擴(kuò)展方法!
          ??@Autowired
          ??private?UserMapper?userMapper;
          ??@Test
          ??void?contextLoads()?{
          ????//?參數(shù)是一個(gè) Wrapper ,條件構(gòu)造器,這里我們先設(shè)置條件為空,查詢所有。
          ????List?users?=?userMapper.selectList(null);
          ????users.forEach(System.out::println);
          ?}
          }?

          所有數(shù)據(jù)輸出

          配置日志

          我們所有的sql現(xiàn)在是不可見的,我們希望知道它是怎么執(zhí)行的,所有我們要配置日志的輸出 application.yml文件添加日志配置

          #配置日志
          mybatis-plus:
          ??configuration:
          ????log-impl:?org.apache.ibatis.logging.stdout.StdOutImpl

          查看執(zhí)行sql的日志信息

          三.Mybatis-plus的CRUD

          插入操作

          //?測(cè)試插入
          ????@Test
          ????public?void?testInsert(){
          ????????User?user?=?new?User();
          ????????user.setName("kwhua_mybatis-plus_insertTest");
          ????????user.setAge(15);
          ????????user.setEmail("[email protected]");

          ????????int?result?=?userMapper.insert(user);?//?幫我們自動(dòng)生成id
          ????????System.out.println(result);?//?受影響的行數(shù)
          ????????System.out.println(user);?//?看到id會(huì)自動(dòng)填充。????}??

          看到id會(huì)自動(dòng)填充。數(shù)據(jù)庫(kù)插入的id的默認(rèn)值為:全局的唯一id

          主鍵生成策略

          1)主鍵自增 1、實(shí)體類字段上 @TableId(type = IdType.AUTO)

          2、數(shù)據(jù)庫(kù)id字段設(shè)置為自增!3、再次測(cè)試(可以看到id值比上次插入的大1)id的生成策略源碼解釋

          圖片
          public?enum?IdType?{
          ??AUTO(0),?//?數(shù)據(jù)庫(kù)id自增
          ??NONE(1),?//?未設(shè)置主鍵
          ??INPUT(2),?//?手動(dòng)輸入
          ??ID_WORKER(3),?//?默認(rèn)的方式,全局唯一id
          ??UUID(4),?//?全局唯一id?uuid
          ??ID_WORKER_STR(5);?//ID_WORKER?字符串表示法
          }

          以上不再逐一測(cè)試。

          更新操作

          ?@Test
          ????public?void?testUpdate(){
          ????????User?user?=?new?User();
          ????????//?通過條件自動(dòng)拼接動(dòng)態(tài)sql
          ????????user.setId(1302223874217295874L);
          ????????user.setName("kwhua_mybatis-plus_updateTest");
          ????????user.setAge(20);
          ????????//?注意:updateById 但是參數(shù)是一個(gè)對(duì)象!
          ????????int?i?=?userMapper.updateById(user);
          ????????System.out.println(i);
          ????}
          圖片

          自動(dòng)填充

          創(chuàng)建時(shí)間、修改時(shí)間!這兩個(gè)字段操作都是自動(dòng)化完成的,我們不希望手動(dòng)更新!阿里巴巴開發(fā)手冊(cè):所有的數(shù)據(jù)庫(kù)表都要配置上gmt_create、gmt_modified!而且需要自動(dòng)化!

          方式一:數(shù)據(jù)庫(kù)級(jí)別(工作中一般不用)

          1、在表中新增字段 gmt_create, gmt_modified

          2、把實(shí)體類同步

          private?Date?gmtCreate;
          private?Date?gmtModified;

          3、再次查看

          方式二:代碼級(jí)別 1、刪除數(shù)據(jù)庫(kù)的默認(rèn)值、更新操作!

          2、實(shí)體類字段屬性上需要增加注解

          ????//?字段添加填充內(nèi)容
          ????@TableField(fill?=?FieldFill.INSERT)
          ????private?Date?gmt_create;

          ????@TableField(fill?=?FieldFill.INSERT_UPDATE)
          ????private?Date?gmt_modified;

          3、編寫處理器來處理這個(gè)注解即可!

          @Slf4j
          @Component?//?一定不要忘記把處理器加到IOC容器中!
          public?class?MyMetaObjectHandler?implements?MetaObjectHandler?{
          ????//?插入時(shí)的填充策略
          ????@Override
          ????public?void?insertFill(MetaObject?metaObject)?{
          ????????log.info("start?insert?fill.....");
          ????????//?setFieldValByName(String?fieldName,?Object?fieldVal,?MetaObject?metaObject
          ????????this.setFieldValByName("gmt_create",new?Date(),metaObject);
          ????????this.setFieldValByName("gmt_modified",new?Date(),metaObject);
          ????}

          ????//?更新時(shí)的填充策略
          ????@Override
          ????public?void?updateFill(MetaObject?metaObject)?{
          ????????log.info("start?update?fill.....");
          ????????this.setFieldValByName("gmt_modified",new?Date(),metaObject);
          ????}
          }

          4、測(cè)試插入和更新,檢查時(shí)間變化。

          樂觀鎖

          樂觀鎖 : 顧名思義,十分樂觀,它總是認(rèn)為不會(huì)出現(xiàn)問題,無論干什么不去上鎖!如果出現(xiàn)了問題, 再次更新值測(cè)試 悲觀鎖:顧名思義,十分悲觀,它總是認(rèn)為總是出現(xiàn)問題,無論干什么都會(huì)上鎖!再去操作!

          樂觀鎖實(shí)現(xiàn)方式:

          取出記錄時(shí),獲取當(dāng)前version 更新時(shí),帶上這個(gè)version 執(zhí)行更新時(shí), set version = newVersion where version = oldVersion 如果version不對(duì),就更新失敗

          樂觀鎖:1、先查詢,獲得版本號(hào) version = 1

          --?A
          update?user?set?name?=?"kwhua",?version?=?version?+?1
          where?id?=?2?and?version?=?1
          -- B 線程搶先完成,這個(gè)時(shí)候 version = 2,會(huì)導(dǎo)致 A 修改失敗!
          update?user?set?name?=?"kwhua",?version?=?version?+?1
          where?id?=?2?and?version?=?1

          樂觀鎖測(cè)試

          1、給數(shù)據(jù)庫(kù)中增加version字段!

          圖片

          2、實(shí)體類加對(duì)應(yīng)的字段

          ????@Version?//樂觀鎖Version注解
          ????private?Integer?version;

          3、注冊(cè)組件

          //?掃描我們的?mapper?文件夾
          @MapperScan("com.kwhua.mapper")
          @EnableTransactionManagement
          @Configuration?//?配置類
          public?class?MyBatisPlusConfig?{
          ????//?注冊(cè)樂觀鎖插件
          ????@Bean
          ????public?OptimisticLockerInterceptor?optimisticLockerInterceptor()?{
          ????????return?new?OptimisticLockerInterceptor();
          ????}
          ???}

          4、測(cè)試

          //?測(cè)試樂觀鎖成功!
          ????@Test
          ????public?void?testOptimisticLocker(){
          ????????//?1、查詢用戶信息
          ????????User?user?=?userMapper.selectById(1L);
          ????????//?2、修改用戶信息
          ????????user.setName("kwhua");
          ????????user.setEmail("[email protected]");
          ????????//?3、執(zhí)行更新操作
          ????????userMapper.updateById(user);
          ????}

          version字段已經(jīng)由1變成了2

          //?測(cè)試樂觀鎖失敗!多線程下
          ????@Test
          ????public?void?testOptimisticLocker2(){

          ????????//?線程?1
          ????????User?user?=?userMapper.selectById(1L);
          ????????user.setName("kwhua111");
          ????????user.setEmail("[email protected]");

          ????????//?模擬另外一個(gè)線程執(zhí)行了插隊(duì)操作
          ????????User?user2?=?userMapper.selectById(1L);
          ????????user2.setName("kwhua222");
          ????????user2.setEmail("[email protected]");
          ????????userMapper.updateById(user2);

          ????????//?自旋鎖來多次嘗試提交!
          ????????userMapper.updateById(user);?//?如果沒有樂觀鎖就會(huì)覆蓋插隊(duì)線程的值!
          ????}

          圖片

          可以看到線程1執(zhí)行更新失敗

          查詢操作

          //?測(cè)試查詢
          ????@Test
          ????public?void?testSelectById(){
          ????????User?user?=?userMapper.selectById(1L);
          ????????System.out.println(user);
          ????}

          ????//?測(cè)試批量查詢!
          ????@Test
          ????public?void?testSelectByBatchId(){
          ????????List?users?=?userMapper.selectBatchIds(Arrays.asList(1,?2,?3));
          ????????users.forEach(System.out::println);
          ????}

          ????//?按條件查詢之一使用map操作
          ????@Test
          ????public?void?testSelectByBatchIds(){
          ????????HashMap?map?=?new?HashMap<>();
          ????????//?自定義要查詢
          ????????map.put("name","kwhua");
          ????????map.put("age",15);

          ????????List?users?=?userMapper.selectByMap(map);
          ????????users.forEach(System.out::println);
          ????}

          1、配置攔截器組件

          //?分頁(yè)插件
          @Bean
          public?PaginationInterceptor?paginationInterceptor()?{
          ??return??new?PaginationInterceptor();
          }

          2、直接使用Page對(duì)象即可!

          //?測(cè)試分頁(yè)查詢
          @Test
          public?void?testPage(){
          ??//?參數(shù)一:當(dāng)前頁(yè)
          ??//?參數(shù)二:頁(yè)面大小
          ??Page?page?=?new?Page<>(2,5);
          ??userMapper.selectPage(page,null);
          ??page.getRecords().forEach(System.out::println);
          ??System.out.println(page.getTotal());
          }

          物理刪除

          //?測(cè)試刪除
          ????@Test
          ????public?void?testDeleteById(){
          ????????userMapper.deleteById(1L);
          ????}

          ????//?通過id批量刪除
          ????@Test
          ????public?void?testDeleteBatchId(){
          ????????userMapper.deleteBatchIds(Arrays.asList(2L,3L));
          ????}

          ????//?通過map刪除
          ????@Test
          ????public?void?testDeleteMap(){
          ????????HashMap?map?=?new?HashMap<>();
          ????????map.put("name","kwhua");
          ????????userMapper.deleteByMap(map);
          ????}

          邏輯刪除

          物理刪除 :從數(shù)據(jù)庫(kù)中直接移除 邏輯刪除 :在數(shù)據(jù)庫(kù)中沒有被移除,而是通過一個(gè)變量來讓它失效!deleted = 0 => deleted = 1 管理員可以查看被刪除的記錄!防止數(shù)據(jù)的丟失,類似于回收站!

          1、在數(shù)據(jù)表中增加一個(gè) deleted 字段2、實(shí)體類中增加屬性

          ?@TableLogic?//邏輯刪除
          ?private?Integer?deleted;

          3、配置

          //?邏輯刪除組件!
          ????@Bean
          ????public?ISqlInjector?sqlInjector()?{
          ????????return?new?LogicSqlInjector();
          ????}

          配置文件配置

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

          4、測(cè)試 測(cè)試刪除

          圖片

          字段值也從0修改成了1測(cè)試查詢

          圖片

          性能分析插件

          作用:性能分析攔截器,用于輸出每條 SQL 語(yǔ)句及其執(zhí)行時(shí)間 MP也提供性能分析插件,如果超過這個(gè)時(shí)間就停止運(yùn)行!1、導(dǎo)入插件

          ???/**
          ?????*?SQL執(zhí)行效率插件
          ?????*/

          ????@Bean
          ????@Profile({"dev","test"})//?設(shè)置?dev?test?環(huán)境開啟,保證我們的效率
          ????public?PerformanceInterceptor?performanceInterceptor()?{
          ????????PerformanceInterceptor?performanceInterceptor?=?new?PerformanceInterceptor();
          ????????performanceInterceptor.setMaxTime(100);?//ms?設(shè)置sql執(zhí)行的最大時(shí)間,如果超過了則不執(zhí)行
          ????????performanceInterceptor.setFormat(true);
          ????????return?performanceInterceptor;
          ????}

          圖片

          條件構(gòu)造器(Wrapper)

          isNotNull .gt

          @Test
          ????void?contextLoads()?{
          ????????//?查詢name不為空的用戶,并且郵箱不為空的用戶,年齡大于等于12
          ????????QueryWrapper?wrapper?=?new?QueryWrapper<>();
          ????????wrapper
          ????????????????.isNotNull("name")?//不為空
          ????????????????.isNotNull("email")
          ????????????????.ge("age",18);
          ????????userMapper.selectList(wrapper).forEach(System.out::println);?//?和我們剛才學(xué)習(xí)的map對(duì)比一下
          ????}
          圖片

          .eq

          ?@Test
          ????void?test2(){
          ????????//?查詢名字kwhua
          ????????QueryWrapper?wrapper?=?new?QueryWrapper<>();
          ????????wrapper.eq("name","kwhua");
          ????????User?user?=?userMapper.selectOne(wrapper);?//?查詢一個(gè)數(shù)據(jù)用selectOne,查詢多個(gè)結(jié)果使用List?或者?Map
          ????????System.out.println(user);
          ????}

          其他方法可以自己測(cè)試...

          代碼自動(dòng)生成器

          //?代碼自動(dòng)生成器
          public?class?generateCode?{
          ???public?static?void?main(String[]?args)?{
          ????//?需要構(gòu)建一個(gè)?代碼自動(dòng)生成器?對(duì)象
          ????AutoGenerator?mpg?=?new?AutoGenerator();
          ????//?配置策略
          ????//?1、全局配置
          ????GlobalConfig?gc?=?new?GlobalConfig();
          ????String?projectPath?=?System.getProperty("user.dir");
          ????gc.setOutputDir(projectPath+"/src/main/java");
          ????gc.setAuthor("kwhua");//作者名稱
          ????gc.setOpen(false);
          ????gc.setFileOverride(false);?//?是否覆蓋
          ????gc.setIdType(IdType.ID_WORKER);
          ????gc.setDateType(DateType.ONLY_DATE);
          ????gc.setSwagger2(true);//實(shí)體屬性?Swagger2?注解

          ????//?自定義文件命名,注意?%s 會(huì)自動(dòng)填充表實(shí)體屬性!
          ????gc.setServiceName("%sService");?
          ????gc.setControllerName("%sController");
          ????gc.setServiceName("%sService");
          ????gc.setServiceImplName("%sServiceImpl");
          ????gc.setMapperName("%sMapper");
          ????gc.setXmlName("%sMapper");

          ????mpg.setGlobalConfig(gc);

          ????//2、設(shè)置數(shù)據(jù)源
          ????DataSourceConfig?dsc?=?new?DataSourceConfig();
          ????dsc.setUrl("jdbc:mysql://localhost:3306/kwhua_test?
          useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"
          );
          ????dsc.setDriverName("com.mysql.cj.jdbc.Driver");
          ????//?dsc.setDriverName("com.mysql.jdbc.Driver");?//mysql5.6以下的驅(qū)動(dòng)
          ????dsc.setUsername("root");
          ????dsc.setPassword("root");
          ????dsc.setDbType(DbType.MYSQL);
          ????mpg.setDataSource(dsc);
          ????//3、包的配置
          ????PackageConfig?pc?=?new?PackageConfig();
          ????pc.setParent("com.kwhua");?//包名
          ????pc.setModuleName("model");?//模塊名
          ????pc.setEntity("entity");
          ????pc.setMapper("mapper");
          ????pc.setService("service");
          ????pc.setController("controller");
          ????mpg.setPackageInfo(pc);

          ????//4、策略配置
          ????StrategyConfig?strategy?=?new?StrategyConfig();
          ????strategy.setInclude("user","course");?//?設(shè)置要映射的表名
          ????strategy.setNaming(NamingStrategy.underline_to_camel);
          ????strategy.setColumnNaming(NamingStrategy.underline_to_camel);
          ????strategy.setEntityLombokModel(true);?//?自動(dòng)lombok;
          ????strategy.setLogicDeleteFieldName("deleted");
          ????//?自動(dòng)填充配置
          ????TableFill?gmtCreate?=?new?TableFill("gmt_create",?FieldFill.INSERT);
          ????TableFill?gmtModified?=?new?TableFill("gmt_modified",FieldFill.INSERT_UPDATE);
          ????ArrayList?tableFills?=?new?ArrayList<>();
          ????tableFills.add(gmtCreate);
          ????tableFills.add(gmtModified);
          ????strategy.setTableFillList(tableFills);
          ????//?樂觀鎖
          ????strategy.setVersionFieldName("version");
          ????//根據(jù)你的表名來建對(duì)應(yīng)的類名,如果你的表名沒有下劃線,比如test,那么你就可以取消這一步
          ????strategy.setTablePrefix("t_");
          ????strategy.setRestControllerStyle(true);?//rest請(qǐng)求
          ????//自動(dòng)轉(zhuǎn)下劃線,比如localhost:8080/hello_id_2
          ????strategy.setControllerMappingHyphenStyle(true);?
          ????mpg.setStrategy(strategy);
          ????mpg.execute();?//執(zhí)行
          ?}
          }

          執(zhí)行主方法即可生成對(duì)應(yīng)代碼

          更多好文章

          1. Java高并發(fā)系列(共34篇)
          2. MySql高手系列(共27篇)
          3. Maven高手系列(共10篇)
          4. Mybatis系列(共12篇)
          5. 聊聊db和緩存一致性常見的實(shí)現(xiàn)方式
          6. 接口冪等性這么重要,它是什么?怎么實(shí)現(xiàn)?
          7. 泛型,有點(diǎn)難度,會(huì)讓很多人懵逼,那是因?yàn)槟銢]有看這篇文章!

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  毛片黄色 | 香蕉伊人av | 蜜桃视频在线无码播放 | 日皮视频免费看 | 国产精品秘 久久久久久 |