mybatis中如何参数化表名

how to parameterize tablename in mybatis

我想参数化 table_name:t_user_address_book(uid/500000)。 例如:当 uid = 1000 时,table_name = t_user_address_book0; 当 uid = 500001 时,table_name = t_user_address_book1; 怎么写?

public interface UserAddressBookMapper {
    @Insert("insert into t_user_address_book? values(...)")
    int upsert(Long uid, UserAddressBookMsg userAddressBookMsg);
}

快速响应将是 "no"。不能给tablename作为参数,因为mybatis使用的是prepared statements

我建议使用 table 名称作为变量,并将其提供给语句字符串。 例如:

public interface UserAddressBookMapper { 

static String tableName;
static void setTableName(String name) {
  tableName = name;
}

@Insert({"insert into", tableName, "values(...)"})
int upsert(UserAddressBookMsg userAddressBookMsg);

您必须在调用该方法之前设置 tableName

你可以选择table和Mybatis XML代码:

<choose>
  <when test="uid gt 1000000">
    <bind name="tableName" value="t_user_address_book2" />
  </when>
  <when test="uid gt 500000">
    <bind name="tableName" value="t_user_address_book1" />
  </when>
  <otherwise>
    <bind name="tableName" value="t_user_address_book0" />
  </otherwise>
</choose>

或者您可以在 java 中计算 table 名称并将其作为参数传递。

无论您选择什么,查询中的 table name 参数都必须使用 $ 符号而不是 # 来引用,因为该值必须按原样替换占位符查询的一部分而不是 interpreted/bound/escaped 作为参数是:

INSERT INTO ${tableName} ...

尽管使用了 XML,您仍可以使用 <script> 标签在查询周围添加注释:

@Insert({"<script>", 
         "<choose> ...", 
         "INSERT ..."
         "</script>"
})

另外在使用带注解的Mapper接口时,参数的命名需要超过1个:

@Insert("INSERT INTO table VALUES(#{uid}, #{userAddressBookMsg.propertyName1})")
int upsert(upsert(@Param("uid")Long uid, @Param("userAddressBookMsg") UserAddressBookMsg userAddressBookMsg);

但是,您似乎想拆分成多个 table 以解决体积问题,这处理起来非常复杂,但最好保留一个 table 并在 DB 上四处看看关于索引和分区的方面。