zoukankan      html  css  js  c++  java
  • mybatis-plus 狂神说笔记

    MyBatis-plus

    CRUD

    Insert

    问题:mybatis-plus进行插入的时候会自动生成主键

        void insert() {
            User user = new User();
            user.setName("yogurt");
            user.setAge(15);
            user.setEmail("128@qq.com");
            userMapper.insert(user);
        }
    

    image-20210315165845342

    主键生成策略

    /**
     * 数据库ID自增
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型
     */
    NONE(1),
    /**
     * 用户输入ID
     * 该类型可以通过自己注册自动填充插件进行填充
     */
    INPUT(2),
    
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 全局唯一ID (idWorker)
     */
    ID_WORKER(3),
    /**
     * 全局唯一ID (UUID)
     */
    UUID(4),
    /**
     * 字符串全局唯一ID (idWorker 的字符串表示)
     */
    ID_WORKER_STR(5);
    

    如果不配置默认的就是ID_WORKER,是使用雪花算法创建的全局唯一的ID。

    update

    public void Update(){
        User user = new User();
        user.setName("yogurt11");
        user.setAge(15);
        user.setEmail("128@qq.com");
        user.setId(1371386560893714434L);
        userMapper.updateById(user);
    }
    

    image-20210315171134021

    mybatis-plus会自动拼接动态sql。

    自动添加

    创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新!
    阿里巴巴开发手册:所有的数据库表: gmt_create、 gmt_modified几乎所有的表都要配置上!而且需要自动化!

    方式一:数据库级别实现,开发时不推荐使用,是不允许修改数据库的

    1. 改变表,默认值写上CURRENT_TIMESTAMP

      image-20210315172720807

    2. 测试成功image-20210315172804396

    方式二:代码级别实现

    1. 修改表

      image-20210315172940427

    2. 修改实体类

      @TableField(fill = FieldFill.INSERT)
      private Date createTime;
      
      @TableField(fill = FieldFill.INSERT_UPDATE)
      private Date updateTime;
      
    3. 添加处理器,mybatis-plus版本不同处理方式不一样,看官网

      @Slf4j
      @Component //一定要进行注册
      public class MyMetaObjectHandler implements MetaObjectHandler {
          @Override
          public void insertFill(MetaObject metaObject) {
              log.info("start insert fill ....");
              this.setFieldValByName("createTime",new Date(),metaObject);
              this.setFieldValByName("updateTime",new Date(),metaObject);
          }
      
          @Override
          public void updateFill(MetaObject metaObject) {
              log.info("start update fill ....");
              this.setFieldValByName("updateTime",new Date(),metaObject);
          }
      }
      
    4. 测试结果

      image-20210315173833997

    乐观锁

    简介

    乐观锁:乐观锁总是认为线程是安全的,直到出现了问题再进行加锁处理。

    1. 取出一行记录时会取出里面的Version字段
    2. 更新字段是会带上这个Version字段,并判断该Version子段是否是之前取出的那个Veriosn
    3. 如果第二步没有问题则更新成功并且Version = Version + 1,如果判断失败则不会进行更新操作

    实现步骤

    1. 在数据库里面添加veriosn字段

      image-20210315194158943

    2. 修改pojo

      @Version
      private Integer version;
      
    3. 在配置文件里面添加配置类

      @Configuration
      @MapperScan("com.yogurt.mybatisplus_study.mapper")
      public class MybatisPlusConfig {
      
          @Bean
          public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
              return interceptor;
          }
      }
      
    4. 测试

      @Test
      public void optimisticLockTest() {
          //取出数据
          User user = userMapper.selectById(1L);
          user.setAge(50);
      
          //模拟多线程B对它操作
          User user1 = userMapper.selectById(1L);
          user1.setAge(55);
          userMapper.updateById(user1);
      
          //这次更新会失败,因为这样更新会覆盖掉user1的数据
          userMapper.updateById(user);
      }
      
    5. 结果

      image-20210315195457379

    select

    1. 通过多个id查询

      public void selectByIds(){
          List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
          users.forEach(System.out::println);
      }
      
    2. 使用map进行条件查询

      @Test
      public void selectByMap(){
          HashMap<String, Object> map = new HashMap<>();
          map.put("name","yogurt");
          List<User> users = userMapper.selectByMap(map);
          users.forEach(System.out::println);
      }
      
    3. 分页查询

      1. 添加插件

        //分页插件
        @Bean
        public PaginationInterceptor paginationInterceptor () {
            return new PaginationInterceptor();
        }
        
      2. 查询

        @Test
        public void selectByPage(){
            Page<User> userPage = new Page<>(1,5);
            IPage<User> userIPage = userMapper.selectPage(userPage, null);
            //userPage和userIPage中都有数据
            userPage.getRecords().forEach(System.out::println);
            System.out.println("total -> " + userPage.getTotal() + "  pages -> " + userPage.getPages());
        }
        

    delete

    1. 通过id删除,返回的是删除的行数
    public void deleteById(){
        int result = userMapper.deleteById(1371394747445358594L);
        System.out.println("result -> " + result);
    }
    
    @Test
    public void deleteByIds() {
        int result = userMapper.deleteBatchIds(Arrays.asList(1371392321954799617L, 1371392128916234242L));
        System.out.println("result -> " + result);
    }
    
    1. 条件删除,返回的是删除的行数

      @Test
      public void deleteByMap() {
          HashMap<String, Object> map = new HashMap<>();
          map.put("name","yogurt");
          int result = userMapper.deleteByMap(map);
          System.out.println("result -> " + result);
      }
      

    逻辑删除

    1. 在数据库里面添加逻辑字段delete

      image-20210316143305105

    2. 实体类中添加属性

      @TableLogic
      private Integer deleted;
      
    3. 添加配置

      //逻辑删除插件
      @Bean
      public LogicSqlInjector logicSqlInjector() {
          return new LogicSqlInjector();
      }
      
      global-config:
        db-config:
          logic-delete-value: 1
          logic-not-delete-value: 0
      
    4. 测试

      可以看到删除操作变成了更新操作,就是把delete字段由0 -> 1

      image-20210316143518867

      执行查询的时候会自动拼接上 and delete = 0

      image-20210316143702362

    总结

    mybatis-plus插件的注入时,版本不同,注入的方式不一样。

    mybatis-plus插件都在另外的依赖mybatis-plus-extension里

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

    配置日志

    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    

    条件构造器

    1. 名字和邮箱不为空且年龄 < 12的用户

      void test1() {
         //名字和邮箱不为空且年龄 < 12的用户
          QueryWrapper<User> wrapper = new QueryWrapper<>();
          wrapper.isNotNull("name")
                  .isNotNull("email")
                  .le("age",12);
          List<User> users = userMapper.selectList(wrapper);
          users.forEach(System.out::println);
      }
      
    2. 查询名字为yogurt的用户,也可以通过map来实现

      void test2() {
          //查询名字为yogurt11的用户
          QueryWrapper<User> wrapper = new QueryWrapper<>();
          wrapper.eq("name","yogurt11");
          List<User> users = userMapper.selectList(wrapper);
          users.forEach(System.out::println);
      }
      
    3. 查询年龄 > 18 且 < 25的用户数量

      @Test
      void test3() {
          //查询年龄 >= 21 且 < 24的用户数量
          QueryWrapper<User> wrapper = new QueryWrapper<>();
          wrapper.between("age",21,24);
          List<User> users = userMapper.selectList(wrapper);
          users.forEach(System.out::println);
      }
      
    4. 名字中不包含e的且以T开头邮箱的用户

      void test4() {
          //名字中不包含e的且以T开头邮箱的用户
          QueryWrapper<User> wrapper = new QueryWrapper<>();
          //likeRight = xx% 百分号在右边
          wrapper.notLike("name","e")
                  .likeRight("email","t");
          List<User> users = userMapper.selectList(wrapper);
          users.forEach(System.out::println);
      }
      

    代码生成器

    AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

    1. 添加依赖

      <!--代码生成器-->
      <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-generator</artifactId>
          <version>3.0.5</version>
      </dependency>
      <!--代码生成器模板引擎-->
      <dependency>
          <groupId>org.apache.velocity</groupId>
          <artifactId>velocity-engine-core</artifactId>
          <version>2.3</version>
      </dependency>
      
      <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger2</artifactId>
          <version>2.7.0</version>
      </dependency>
      
      
      <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
      <dependency>
          <groupId>io.springfox</groupId>
          <artifactId>springfox-swagger-ui</artifactId>
          <version>2.7.0</version>
      </dependency>
      
    2. 编写配置类

      public class CodeGeneration {
          public static void main(String[] args) {
              AutoGenerator mpg = new AutoGenerator();
              // 配置策略
              // 1、全局配置
              GlobalConfig gc = new GlobalConfig();
              String projectPath = System.getProperty("user.dir");
              gc.setOutputDir(projectPath+"/src/main/java");
              gc.setAuthor("iandf");
              gc.setOpen(false);
              gc.setFileOverride(false); // 是否覆盖
              gc.setServiceName("%sService"); // 去Service的I前缀
              gc.setIdType(IdType.ID_WORKER);
              gc.setDateType(DateType.ONLY_DATE);
              gc.setSwagger2(true);
              mpg.setGlobalConfig(gc);
      
              //2、设置数据源
              DataSourceConfig dsc = new DataSourceConfig();
              dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus_study?useUnicode=true&characterEncoding=utf8&useSSL=true");
              dsc.setDriverName("com.mysql.cj.jdbc.Driver");
              dsc.setUsername("root");
              dsc.setPassword("123456");
              dsc.setDbType(DbType.MYSQL);//设置数据库类型
              mpg.setDataSource(dsc);
      
              //3、包的配置
              PackageConfig pc = new PackageConfig();
              pc.setModuleName("user");
              pc.setParent("com.yogurt.mybatisplus_study");
              pc.setEntity("entity");
              pc.setMapper("mapper");
              pc.setService("service");
              pc.setController("controller");
              mpg.setPackageInfo(pc);
      
              //4、策略配置
              StrategyConfig strategy = new StrategyConfig();
              strategy.setInclude("user"); // 设置要映射的表名
              strategy.setNaming(NamingStrategy.underline_to_camel);//下划线转驼峰
              strategy.setColumnNaming(NamingStrategy.underline_to_camel);
              strategy.setEntityLombokModel(true); // 自动lombok;
              strategy.setLogicDeleteFieldName("deleted"); //设置逻辑删除属性名
      
              // 自动填充配置
              TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
              TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
              ArrayList<TableFill> tableFills = new ArrayList<>();
              tableFills.add(gmtCreate);
              tableFills.add(gmtModified);
              strategy.setTableFillList(tableFills);
              // 乐观锁
              strategy.setVersionFieldName("version");
              strategy.setRestControllerStyle(true);
              strategy.setControllerMappingHyphenStyle(true); //localhost:8080/hello_id_2
              mpg.setStrategy(strategy);
              mpg.execute(); //执行
          }
      }
      
    3. 执行之后生成的效果

      image-20210316161117404

  • 相关阅读:
    C语言调试示例
    Tiff格式详解(转载)
    指纹
    twitter
    baidu
    NoSuchMethodError随记
    IllegalArgumentException异常
    Springboot2.2.9接入阿里云ES(带高亮查询)
    阿里云ECS安装cnpm
    阿里云ECS安装docker
  • 原文地址:https://www.cnblogs.com/iandf/p/14544174.html
Copyright © 2011-2022 走看看