当前使用版本(必填,否则不予处理)

mybatis-plus v3.5.1

该问题是如何引起的?(确定最新版也有问题再提!!!)

在表的字段外键关联查询时的子查询中无法动态加上租户ID

重现步骤(如果有就写完整)

1,主表T_AT_SESSION中有字段USERID,该字段关联了用户表T_USER在xml mapper中使用association进行关联查询,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.system.mapper.AtSessionMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.test.system.entity.AtSession">
        <id column="USERID" property="userId" />
        <result column="CID" property="cid" />
        <result column="LAST_OP_TIME" property="lastOpTime"  typeHandler="com.test.utils.mybatis.TimeOffsetTypeHandler"/>
        <result column="SESSIONID" property="sessionId" />
        <result column="LOGIN_DATE" property="loginDate"  typeHandler="com.test.utils.mybatis.TimeOffsetTypeHandler"/>
        <result column="OPER_HOST" property="operHost" />
        <result column="OPER_OS" property="operOs" />
        <result column="OPER_BROWSER" property="operBrowser" />
        <result column="VERSION" property="version" />
        <association column="USERID" property="user" javaType="com.test.system.entity.User"
            select="com.test.system.mapper.UserMapper.selectById" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        USERID,CID, LAST_OP_TIME,
        SESSIONID,LOGIN_DATE,OPER_HOST,OPER_OS,OPER_BROWSER,VERSION
    </sql>
</mapper>

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

2, 在log中发现子查询T_USER时并没有动态增加TenantIdColumn=“CID”,如下所示:

[INFO ] [2022/05/10 12:12:08] [http-nio-8082-exec-2] [com.test.base.interceptor.HandleInterceptor] - HandleInterceptor--handler:com.test.system.controller.RoleController#list(int, int, Map)
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@71a68078]
original SQL: SELECT * FROM T_AT_SESSION WHERE USERID=? 
SQL to parse, SQL: SELECT * FROM T_AT_SESSION WHERE USERID=? 
parse the finished SQL: SELECT * FROM T_AT_SESSION WHERE USERID = ? AND T_AT_SESSION.CID = 1
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@6f4a4553] will be managed by Spring
==>  Preparing: SELECT * FROM T_AT_SESSION WHERE USERID = ? AND T_AT_SESSION.CID = 1
==> Parameters: 0abb14edd63ad482619dae181c9c6b01(String)
<==    Columns: USERID, CID, SESSIONID, LOGIN_DATE, OPER_HOST, OPER_OS, OPER_BROWSER, LAST_OP_TIME, VERSION
<==        Row: 0abb14edd63ad482619dae181c9c6b01, 1, a73f8333-6afa-4ebe-8fa7-20c40fc5fd33, 2022-05-10 12:08:23, 127.0.0.1, Windows 10, Chrome 8, 2022-05-10 12:11:26.000546, 10
====>  Preparing: SELECT * FROM T_USER WHERE USERID=?
====> Parameters: 0abb14edd63ad482619dae181c9c6b01(String)
<====    Columns: USERID, CID, NAME, LOGIN_NAME, SALT, PASSWORD, EMAIL, PHONE, MOBILE, FAX, ADDRESS, FAIL_TIMES, INIT_PWD, STATUS, LOCK_REASON, PWD_MODIFY_DATE, HISTORY_PWD, LAST_LOGIN_DATE, CREATOR_ID, CREATE_DATE, MODIFIER_ID, LAST_MODIFY_DATE, LAST_ROLE, VERSION
<====        Row: 0abb14edd63ad482619dae181c9c6b01, 1, kevin, kevin, 76b6742109303a58, 855b3cc1bb2e6a97a87958f57d0da93562f407fece3e50a2348473f8d263a60b, , , , , , 0, 0, 0, null, 2022-03-22 18:16:18, 76b6742109303a58855b3cc1bb2e6a97a87958f57d0da93562f407fece3e50a2348473f8d263a60b, 2022-05-10 12:08:23, 1, 2022-03-22 18:16:01, 1, 2022-03-22 18:16:01, 599571c6094435f813e5acb851a15357, 3
======>  Preparing: SELECT * FROM T_USER WHERE USERID=?
======> Parameters: 1(String)
<======    Columns: USERID, CID, NAME, LOGIN_NAME, SALT, PASSWORD, EMAIL, PHONE, MOBILE, FAX, ADDRESS, FAIL_TIMES, INIT_PWD, STATUS, LOCK_REASON, PWD_MODIFY_DATE, HISTORY_PWD, LAST_LOGIN_DATE, CREATOR_ID, CREATE_DATE, MODIFIER_ID, LAST_MODIFY_DATE, LAST_ROLE, VERSION
<======        Row: 1, 1, administrator, admin, 247b29c80c634031, 5496d0d23e0d4900af586cd8edfdea67c9ff3b2feffbe42d6bc4df00527bb24f, null, null, null, null, null, 0, 0, 0, 1, 2021-06-15 18:47:02, 247b29c80c634031f4b75c3c1bbfb568b89e882240e46d6f388f64e1a3e1e8bd895716ef31510a8e, 2022-03-22 18:15:27, 1, 2013-10-10 12:00:00, 1, 2013-10-10 12:00:00, 1, 193
<======      Total: 1
<====      Total: 1
<==      Total: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@71a68078]

之前的版本v3.2.0使用旧的TenantSqlParser时是可以对子查询也动态添加TenantIdColumn "CID",升级至最新版本v3.5.1反而不行了。

报错信息

外层表T_AT_SESSION是可以动态增加TenantIdColumn "CID"的,如下所示: SELECT * FROM T_AT_SESSION WHERE USERID = ? AND T_AT_SESSION.CID = 1

但,通过进行子表关联查询时,无法在子查询SQL中添加TenantIdColumn "CID",如下所示: ====> Preparing: SELECT * FROM T_USER WHERE USERID=?

Comment From: miemieYaho

association 配置的 select 查询是任何插件都不会走的

Comment From: kevinluoc

association 配置的 select 查询是任何插件都不会走的

这个我不认同,因为我们恢复到mybatis-plus v3.2.0,然后把TenantLineInnerInterceptor改回旧版本的TenantSqlParser,对应的association中对应的子查询是可以正常添加TenantIdColumn "CID",如下恢复旧版的log所示:

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@53c2c402] was not registered for synchronization because synchronization is not active
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@75d7297d] will not be managed by Spring
Original SQL: SELECT  
USERID,SESSIONID,OPER_HOST,OPER_BROWSER,OPER_OS,LOGIN_DATE,LAST_OP_TIME
  FROM T_AT_SESSION 



  ORDER BY LOGIN_DATE DESC , USERID ASC
parser sql: SELECT USERID, SESSIONID, OPER_HOST, OPER_BROWSER, OPER_OS, LOGIN_DATE, LAST_OP_TIME FROM T_AT_SESSION WHERE T_AT_SESSION.CID = 1 ORDER BY LOGIN_DATE DESC, USERID ASC
==>  Preparing: SELECT USERID, SESSIONID, OPER_HOST, OPER_BROWSER, OPER_OS, LOGIN_DATE, LAST_OP_TIME FROM T_AT_SESSION WHERE T_AT_SESSION.CID=1 AND USERID IN(SELECT USERID FROM T_AT_SESSION WHERE T_AT_SESSION.CID = 1 ORDER BY LOGIN_DATE DESC, USERID ASC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY) ORDER BY LOGIN_DATE DESC, USERID ASC 
==> Parameters: 0(Long), 10(Long)
<==    Columns: USERID, SESSIONID, OPER_HOST, OPER_BROWSER, OPER_OS, LOGIN_DATE, LAST_OP_TIME
<==        Row: 68d1631efd519da694f3fe452b5d4242, 8097ff01-336a-453f-ba4a-f9d349b644bd, 127.0.0.1, Chrome 9, Windows 10, 2022-05-10 13:31:03, 2022-05-10 13:35:33.000949
Original SQL: SELECT * FROM T_USER WHERE USERID=? 
parser sql: SELECT * FROM T_USER WHERE USERID = ? AND T_USER.CID = 1
====>  Preparing: SELECT * FROM T_USER WHERE USERID = ? AND T_USER.CID = 1 
====> Parameters: 68d1631efd519da694f3fe452b5d4242(String)
<====    Columns: USERID, CID, NAME, LOGIN_NAME, SALT, PASSWORD, EMAIL, PHONE, MOBILE, FAX, ADDRESS, FAIL_TIMES, INIT_PWD, STATUS, LOCK_REASON, PWD_MODIFY_DATE, HISTORY_PWD, LAST_LOGIN_DATE, CREATOR_ID, CREATE_DATE, MODIFIER_ID, LAST_MODIFY_DATE, LAST_ROLE, VERSION
<====        Row: 68d1631efd519da694f3fe452b5d4242, 1, wing, wing, ac09f1adca4fcc26, 90dbe50a06cb254ef89bbc59d1276c119259ea438685f442949ca8e46a0b2a70, wing.li@lyodssoft.com, 110000, 120000000, 1300000, 1500, 0, 0, 0, null, 2021-10-20 11:53:49, ac09f1adca4fcc2690dbe50a06cb254ef89bbc59d1276c119259ea438685f442949ca8e46a0b2a70, 2022-05-10 13:31:03, 1, 2021-10-20 11:53:30, 1, 2021-12-03 16:28:14, 599571c6094435f813e5acb851a15357, 103
Original SQL: SELECT * FROM T_USER WHERE USERID=? 
parser sql: SELECT * FROM T_USER WHERE USERID = ? AND T_USER.CID = 1
======>  Preparing: SELECT * FROM T_USER WHERE USERID = ? AND T_USER.CID = 1 
======> Parameters: 1(String)
<======    Columns: USERID, CID, NAME, LOGIN_NAME, SALT, PASSWORD, EMAIL, PHONE, MOBILE, FAX, ADDRESS, FAIL_TIMES, INIT_PWD, STATUS, LOCK_REASON, PWD_MODIFY_DATE, HISTORY_PWD, LAST_LOGIN_DATE, CREATOR_ID, CREATE_DATE, MODIFIER_ID, LAST_MODIFY_DATE, LAST_ROLE, VERSION
<======        Row: 1, 1, administrator, admin, 247b29c80c634031, 5496d0d23e0d4900af586cd8edfdea67c9ff3b2feffbe42d6bc4df00527bb24f, null, null, null, null, null, 0, 0, 0, 1, 2021-06-15 18:47:02, 247b29c80c634031f4b75c3c1bbfb568b89e882240e46d6f388f64e1a3e1e8bd895716ef31510a8e, 2022-03-22 18:15:27, 1, 2013-10-10 12:00:00, 1, 2013-10-10 12:00:00, 1, 193
<======      Total: 1
<====      Total: 1
<==        Row: f0595d136a9657bd5610d29397a2ac22, dc80e9b7-5313-41c2-83a7-0027c2d1c7b7, 127.0.0.1, Chrome 55, Windows 10, 2022-05-10 13:27:49, 2022-05-10 13:28:35.000813

Original SQL: SELECT * FROM T_USER WHERE USERID=? parser sql: SELECT * FROM T_USER WHERE USERID = ? AND T_USER.CID = 1