• Mybatis Plus入门进阶:特殊符号、动态条件、公共语句、关联查询、多租户插件


    前言

    Mybatis Plus入门进阶:特殊符号、动态条件、公共语句、关联查询、多租户插件
    隐藏问题:批量插入saveBatch

    注意点

    • mapper.xml中大于、小于需要使用特殊符号

      <     <    小于号
      >     >    大于号
      &    &    和
      '   '    单引号
      "   "    双引号
      <=    <=   小于等于
      >=    >=   大于等于
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 如果需要拼接
      字符串,可以使用 CDATA 包裹起来,让解析器将其视为文本而非标签

      <sql id="exampleSql">
        ', column4) AS combinedColumn
          FROM 
            your_table
        ]]>
      sql>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

    动态条件

    1. 使用if对参数值进行判断,非空才查询

      <if test="roleName != null and roleName != ''">
      	AND r.role_name like concat('%', #{roleName}, '%')
      if>
      
      • 1
      • 2
      • 3
    2. 多个条件判断

      • 使用多个if

        <if test = "">if>
        <if test = "">if>
        
        • 1
        • 2
      • 使用when/otherwise

        <choose>
        	<when test="status == 2">
        		create_time DESC
        	when>
        	<otherwise>
        		create_time
        	otherwise>
        choose>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8

    xml公共语句

    1. 定义

      <sql id="xxx">
         select a from b
      sql>
      
      • 1
      • 2
      • 3
    2. 使用

      <select id = "yyy">
      	<include refId="xxx">include>
      	where name = 'mango'
      select>
      
      • 1
      • 2
      • 3
      • 4

    关联查询

    1. 一对一

      • 正常的查询sql,定义返回的结果类型:resultMap

        <select id="selectRoleAll" resultMap="SysRoleResult">
        	select * from A left join B ...
        select>
        
        <resultMap type="SysRole" id="SysRoleResult">
        	<id     property="roleId"             column="role_id"     />
        	<result property="roleName"           column="role_name"   />
        resultMap>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
    2. 一对多

      • A表与B表关联查询,其中A表与B表为一对多的关系,则查询结果使用

        <resultMap id = "xxx" type="com.xxxx">
        	<id column="id" property="id" />
            <collection property="yyy" ofType=zzz>
            	<result property="no" column="no"/>
            collection>
        resultMap>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
      • 列名重复问题==> 使用别名

      • 分页存在问题(不建议分页时使用)==> 使用select

    相关参考文章:

    动态表名

    当我们想要传的参数是表格的名称或是列名的时候,#{}这种方式就不生效了,需要使用${}

    使用自定义函数

    在xml中,使用了数据库自定义的函数,则需要带上模式名,或者在当前的模式下创建函数

    自定义的函数(达梦数据库),默认是在sysdba下

    主键生成策略

    @TableId注解定义了主键生成的类型,具体查看枚举类IdType.java

    • AUTO

      • 数据库 ID自增,这种情况下将表中主键设置为自增,否则,没有设置主动设置id值进行插入时会报错
    • NONE

      • 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里默认 ASSIGN_ID),注意这里官网文档有误
    • INPUT

      • insert 前自行 set 主键值,在采用IKeyGenerator类型的ID生成器时必须为INPUT
    • ASSIGN_ID

      • 分配ID (主键类型为number或string),默认实现为雪花算法
    • ASSIGN_UUID

      • 分配 UUID

    详细参考

    saveBatch

    1. 特性及问题

      • 拼接sql:如果集合中的某个实体和它的上/下一个不一样,就不会拼接到insert中,而是会单独执行插入语句,所以多个实体不一样(某个字段为null),会拼出多个插入语句

      • 事务:事务回滚,如果在某一个拼接语句中,存在一条数据报错,那么整批会报错,如果上一批语句已经执行过了,则事务不会回滚,已经成功的仍旧是成功

    2. 解决方案:

      • 使用其他的批量插入:this.baseMapper.insertBatchSomeColumn(list);

        • 存在问题:数据库字段默认值不生效,需要手动对对象设值,或者对实体字段设值默认,如果为雪花算法,可使用IdWorker
      • 自定义批量插入

      • 设置插入字段策略

        • 局部字段忽略控制:@TableField(fill = FieldFill.INSERT,insertStrategy = FieldStrategy.IGNORED)

        • 全局

          mybatis-plus:
          	global-config:
          		db-config:
          			insert-strategy: ignored
          
          • 1
          • 2
          • 3
          • 4
        • 参考

    插件:多租户TenantLineInnerInterceptor

    处理逻辑类:BaseMultiTableInnerInterceptor

    • 忽略某个方法,需要重写TenantLineInnerInterceptor中的beforeQuery

    相关文章参考

    引入及使用租户

    忽略多租户隔离自定义注解(未验证)

    1. 新增租户配置信息

      # 租户配置信息
      tenant:
        # 是否开启租户模式
        enable: true
        # 需要排除的多租户的表
        exclusionTable: sys_config,sys_dict_data
        # 租户字段名称
        column: tenant_id
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    2. 对应增加配置类TenantProperties

      @Configuration
      @Getter
      public class TenantProperties {
      
          /**
           * 是否开启租户模式
           */
          @Value("${tenant.enable}")
          private Boolean enable;
      
          /**
           * 多租户字段名称
           */
          @Value("${tenant.column}")
          private String column;
      
          /**
           * 需要排除的多租户的表
           */
          @Value("${tenant.exclusionTable}")
          private List<String> exclusionTable;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    3. 注入重载的租户配置

      @Configuration
      @RequiredArgsConstructor(onConstructor_ = @Autowired)
      @AutoConfigureBefore(MyBatisPlusConfig.class)
      public class TenantConfig {
      
          private final TenantProperties tenantProperties;
      
          @Bean
          public TenantLineInnerInterceptor tenantLineInnerInterceptor() {
              return new TenantLineInnerInterceptor(new TenantLineHandler() {
      
                  @Override
                  public Expression getTenantId() {
                      try {
                          String tenantId = SecurityUtils.getLoginUser().getTenantId();
                          if (tenantId != null) {
                              return new StringValue(tenantId);
                          }
                      } catch (ServiceException e) {
                          e.printStackTrace();
                      }
      
                      return new NullValue();
                  }
      
                  @Override
                  public String getTenantIdColumn() {
                      return tenantProperties.getColumn();
                  }
      
                  @Override
                  public boolean ignoreTable(String tableName) {
                      return tenantProperties.getExclusionTable().stream().anyMatch(
                              (t) -> t.equalsIgnoreCase(tableName)
                      );
                  }
      
                  @Override
                  public boolean ignoreInsert(List columns, String tenantIdColumn) {
                      return TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn);
                  }
              });
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
    4. Mybatis Plus配置增加租户配置

      @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor() {
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              // 多租户插件
              if (tenantProperties.getEnable()) {
                  interceptor.addInnerInterceptor(tenantLineInnerInterceptor);
              }
              return interceptor;
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
  • 相关阅读:
    产品的需求只有一句话,如何破局?
    SpringCloud整合OpenFeign
    基于SpringBoot开发的同城租房系统租房软件APP小程序源码
    【深入浅出玩转FPGA学习3-----基本语法】
    pthread_cancel手册翻译
    vue手写提示组件弹窗
    [附源码]计算机毕业设计springboot勤工俭学管理小程序
    NFT 作品集推荐|Lululand《爱是永恒》
    自注意力机制(Self-attention)【第四章】
    基于python+Django深度学习的音乐推荐方法研究系统设计与实现
  • 原文地址:https://blog.csdn.net/qq_35893033/article/details/133858692