前言
Mybatis Plus入门进阶:特殊符号、动态条件、公共语句、关联查询、多租户插件
隐藏问题:批量插入saveBatch
文章目录
- 前言
- 注意点
- 动态条件
- xml公共语句
- 关联查询
- 动态表名
- 使用自定义函数
- 主键生成策略
- saveBatch
- 插件:多租户TenantLineInnerInterceptor
 
 
注意点
-  mapper.xml中大于、小于需要使用特殊符号 < < 小于号 > > 大于号 & & 和 ' ' 单引号 " " 双引号 <= <= 小于等于 >= >= 大于等于
-  如果需要拼接 <br/> 字符串,可以使用 CDATA 包裹起来,让解析器将其视为文本而非标签 <sql id="exampleSql"><![CDATA[SELECT column1,column2,CONCAT(column3, '<br/>', column4) AS combinedColumnFROM your_table]]> </sql>
动态条件
-  使用if对参数值进行判断,非空才查询 <if test="roleName != null and roleName != ''">AND r.role_name like concat('%', #{roleName}, '%') </if>- 参考
 
-  多个条件判断 -  使用多个if <if test = ""></if> <if test = ""></if>
-  使用when/otherwise <choose><when test="status == 2">create_time DESC</when><otherwise>create_time</otherwise> </choose>
 
-  
xml公共语句
-  定义 <sql id="xxx">select a from b </sql>
-  使用 <select id = "yyy"><include refId="xxx"></include>where name = 'mango' </select>
关联查询
-  一对一 -  正常的查询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>
 
-  
-  一对多 -  A表与B表关联查询,其中A表与B表为一对多的关系,则查询结果使用<collection> <resultMap id = "xxx" type="com.xxxx"><id column="id" property="id" /><collection property="yyy" ofType=zzz><result property="no" column="no"/></collection> </resultMap>
-  列名重复问题==> 使用别名 
-  分页存在问题(不建议分页时使用)==> 使用select 
 
-  
相关参考文章:
-  Mybatis Plus内置的分页查询 
-  collection分页问题总结 
-  collection查询一对多分页数据的Bug 
-  collection分页问题 
动态表名
当我们想要传的参数是表格的名称或是列名的时候,#{}这种方式就不生效了,需要使用${}
使用自定义函数
在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
-  特性及问题 -  拼接sql:如果集合中的某个实体和它的上/下一个不一样,就不会拼接到insert中,而是会单独执行插入语句,所以多个实体不一样(某个字段为null),会拼出多个插入语句 
-  事务:事务回滚,如果在某一个拼接语句中,存在一条数据报错,那么整批会报错,如果上一批语句已经执行过了,则事务不会回滚,已经成功的仍旧是成功 
 
-  
-  解决方案: -  使用其他的批量插入:this.baseMapper.insertBatchSomeColumn(list); - 存在问题:数据库字段默认值不生效,需要手动对对象设值,或者对实体字段设值默认,如果为雪花算法,可使用IdWorker
 
-  自定义批量插入 
-  设置插入字段策略 -  局部字段忽略控制:@TableField(fill = FieldFill.INSERT,insertStrategy = FieldStrategy.IGNORED) 
-  全局 mybatis-plus:global-config:db-config:insert-strategy: ignored
-  参考 
 
-  
 
-  
插件:多租户TenantLineInnerInterceptor
处理逻辑类:BaseMultiTableInnerInterceptor
- 忽略某个方法,需要重写TenantLineInnerInterceptor中的beforeQuery
相关文章参考
引入及使用租户
忽略多租户隔离自定义注解(未验证)
-  新增租户配置信息 # 租户配置信息 tenant:# 是否开启租户模式enable: true# 需要排除的多租户的表exclusionTable: sys_config,sys_dict_data# 租户字段名称column: tenant_id
-  对应增加配置类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; }
-  注入重载的租户配置 @Configuration @RequiredArgsConstructor(onConstructor_ = @Autowired) @AutoConfigureBefore(MyBatisPlusConfig.class) public class TenantConfig {private final TenantProperties tenantProperties;@Beanpublic TenantLineInnerInterceptor tenantLineInnerInterceptor() {return new TenantLineInnerInterceptor(new TenantLineHandler() {@Overridepublic Expression getTenantId() {try {String tenantId = SecurityUtils.getLoginUser().getTenantId();if (tenantId != null) {return new StringValue(tenantId);}} catch (ServiceException e) {e.printStackTrace();}return new NullValue();}@Overridepublic String getTenantIdColumn() {return tenantProperties.getColumn();}@Overridepublic boolean ignoreTable(String tableName) {return tenantProperties.getExclusionTable().stream().anyMatch((t) -> t.equalsIgnoreCase(tableName));}@Overridepublic boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {return TenantLineHandler.super.ignoreInsert(columns, tenantIdColumn);}});} }
-  Mybatis Plus配置增加租户配置 @Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();// 多租户插件if (tenantProperties.getEnable()) {interceptor.addInnerInterceptor(tenantLineInnerInterceptor);}return interceptor;}