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

基于JPA(EclipseLink)和Spring Data按列对查询MSSQL表行

问题描述

现有MSSQL表t1,结构及数据如下:

create table t1 (
  id   int   IDENTITY(1,1),
  col1 int   not null,
  col2 int   not null, 
  constraint t1_UK UNIQUE (col1, col2)
)

表中数据:

id    col1     col2
    1      25      661
    2      25      741
    3      89      661
    4      89      741

对应的JPA实体类T1Entity定义:

@Entity
@Table
class T1Entity {
   @Id
   @GeneratedValue
   private int id;
   @Column
   private int col1;
   @Column
   private int col2;
   // getters, setters
}

需求:查询id为1和4的行,仅通过col1和col2作为查询条件。注意使用findByCol1InAndCol2In(List.of(25, 89), List.of(661, 741))会返回所有样本数据,不符合需求,需实现类似SELECT col1, col2 from t1 where (col1=25 and col2 = 661) OR (col1=89 and col2=741)的查询效果。


解决方案

一、Spring Data JPA结合EclipseLink实现方式

1. 自定义JPQL查询(静态多组条件)

在Repository接口中直接编写JPQL语句,明确指定每组col1+col2的匹配条件:

public interface T1EntityRepository extends JpaRepository<T1Entity, Integer> {

    @Query("SELECT t FROM T1Entity t WHERE (t.col1 = :col1a AND t.col2 = :col2a) OR (t.col1 = :col1b AND t.col2 = :col2b)")
    List<T1Entity> findBySpecifiedColPairs(
        @Param("col1a") int col1a, 
        @Param("col2a") int col2a, 
        @Param("col1b") int col1b, 
        @Param("col2b") int col2b
    );
}

调用时传入对应参数即可:

List<T1Entity> result = repository.findBySpecifiedColPairs(25, 661, 89, 741);

2. 动态行值IN查询(支持任意多组条件)

利用JPQL的行值表达式特性,直接传入多组col1+col2的配对列表,EclipseLink完全支持这种语法:

public interface T1EntityRepository extends JpaRepository<T1Entity, Integer> {

    @Query("SELECT t FROM T1Entity t WHERE (t.col1, t.col2) IN :pairs")
    List<T1Entity> findByColPairs(@Param("pairs") List<Object[]> pairs);
}

调用时构造配对列表:

List<Object[]> pairs = Arrays.asList(
    new Object[]{25, 661},
    new Object[]{89, 741}
);
List<T1Entity> result = repository.findByColPairs(pairs);

3. 使用Specification动态构建查询

如果需要更灵活的动态条件拼接,可以借助JpaSpecificationExecutor:
首先扩展Repository接口:

public interface T1EntityRepository extends JpaRepository<T1Entity, Integer>, JpaSpecificationExecutor<T1Entity> {
}

然后构建查询条件并执行:

Specification<T1Entity> spec = (root, query, cb) -> {
    List<Predicate> predicates = new ArrayList<>();
    // 添加每组col1+col2的匹配条件
    predicates.add(cb.and(cb.equal(root.get("col1"), 25), cb.equal(root.get("col2"), 661)));
    predicates.add(cb.and(cb.equal(root.get("col1"), 89), cb.equal(root.get("col2"), 741)));
    // 用OR拼接所有条件
    return cb.or(predicates.toArray(new Predicate[0]));
};

List<T1Entity> result = repository.findAll(spec);

二、SQL的替代写法(无需OR嵌套AND)

1. 行值构造器IN语法

MSSQL支持直接使用行值的IN匹配,语法简洁:

SELECT id, col1, col2 
FROM t1 
WHERE (col1, col2) IN ((25, 661), (89, 741));

2. JOIN临时表方式

通过JOIN一个包含目标配对的临时表来实现查询,适合复杂场景:

SELECT t.id, t.col1, t.col2
FROM t1 t
JOIN (
    VALUES (25, 661), (89, 741)
) AS temp(c1, c2) 
ON t.col1 = temp.c1 AND t.col2 = temp.c2;

内容的提问来源于stack exchange,提问作者SJ1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:00:17