You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JDBI中使用@BindList结合MySQL的MATCH() AGAINST()函数

解决JDBI绑定列表到MATCH() AGAINST()的问题

核心需求

把原有的NOT IN查询替换为MATCH(request_id) AGAINST()的布尔模式匹配,实现批量排除指定request_id的功能,同时用JDBI安全绑定列表参数。

方案一:代码预处理生成匹配字符串(简单直接)

先在Java代码中将黑名单列表转换为符合MySQL布尔全文搜索格式的字符串,再通过@Bind绑定到SQL中:

  1. Java代码处理列表
import java.util.List;
import java.util.stream.Collectors;

// 假设黑名单ID列表
List<String> blacklistedRequestIds = List.of("req1", "req2", "req3");

// 转换为 "-req1 -req2 -req3" 格式
String searchClause = blacklistedRequestIds.stream()
        .map(id -> "-" + id)
        .collect(Collectors.joining(" "));
  1. JDBI查询注解
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import java.util.List;

public interface LogDao {
    @SqlQuery("""
        SELECT * FROM bcsadmin_log 
        WHERE MATCH(request_id) AGAINST(:searchClause IN BOOLEAN MODE)
        """)
    List<BcsadminLog> getLogsExcludingBlacklisted(@Bind("searchClause") String searchClause);
}

方案二:用JDBI@BindList自定义转换(更优雅)

通过@BindList的elementConverter和separator属性,直接让JDBI处理列表元素的格式转换:

  1. 定义元素转换器
import org.jdbi.v3.core.argument.AttributeConverter;

public class NegativeFulltextConverter implements AttributeConverter<String, String> {
    @Override
    public String convertToDatabaseColumn(String id) {
        // 给每个ID添加负号,用于布尔模式的排除匹配
        return "-" + id;
    }

    @Override
    public String convertToEntityAttribute(String dbValue) {
        // 反向转换(查询结果映射时用,这里可选)
        return dbValue.substring(1);
    }
}
  1. JDBI查询注解
import org.jdbi.v3.sqlobject.customizer.BindList;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import java.util.List;

public interface LogDao {
    @SqlQuery("""
        SELECT * FROM bcsadmin_log 
        WHERE MATCH(request_id) AGAINST(:blacklistedRequestIds IN BOOLEAN MODE)
        """)
    List<BcsadminLog> getLogsExcludingBlacklisted(
            @BindList(value = "blacklistedRequestIds", 
                     elementConverter = NegativeFulltextConverter.class, 
                     separator = " ") 
            List<String> blacklistedRequestIds
    );
}

注意事项

  • 全文索引要求:request_id字段必须创建全文索引,否则MATCH()函数会报错。创建索引的SQL示例:
    CREATE FULLTEXT INDEX idx_request_id ON bcsadmin_log(request_id);
    
  • 空列表处理:如果黑名单列表为空,AGAINST('')会返回空结果,需要在代码中判断列表是否为空,若为空则执行无过滤的查询,或者在SQL中添加条件:
    SELECT * FROM bcsadmin_log 
    WHERE (:blacklistedSize = 0 OR MATCH(request_id) AGAINST(:searchClause IN BOOLEAN MODE))
    
    同时绑定列表大小参数@Bind("blacklistedSize") int blacklistedSize。
  • 特殊字符转义:如果request_id包含MySQL全文搜索的特殊字符(如+、-、(、)等),需要在转换器中添加转义逻辑,比如用\\转义特殊字符,避免匹配逻辑出错。

内容的提问来源于stack exchange,提问作者Kim Kakan Andersson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 11:37:04