Ebean使用其他表过滤findList结果

foo*_*bar 1 join filter ebean

在检索对象列表时,我想根据另一个只有ID的表来过滤结果.对象在ORM模型中没有链接,而只是包含一个UUID.

即:

@Entity
class A {
    @Id
    private UUID id;
    private UUID refB; // links to B
}

@Entity
class B {
    @Id
    private UUID id;
    private boolean visible;
}
Run Code Online (Sandbox Code Playgroud)

我想检索B.hidden为假或其中B不存在的所有A.

在SQL中我会做类似的事情

SELECT t0.* FROM a_table t0 LEFT JOIN b_table t1 ON (t0.ref_b = t1.id)
    WHERE t1.hidden IS NULL OR t1.hidden = 0;
Run Code Online (Sandbox Code Playgroud)

我不仅仅使用RawSql的原因是我找不到任何方法在select中使用通配符,因此所有属性都必须在select中进行维护和手动添加.

我也试过了

List<A> listA = Ebean.find(A.class).where()
     .join("LEFT JOIN b_table t1 ON (t0.ref_b = t1.id)")
     .where().in("t1.hidden", "0", "NULL");
Run Code Online (Sandbox Code Playgroud)

但后来我得到一个错误,因为在"LEFT JOIN"之前放置了WHERE.

我认为"正确"的方式是将"私有UUID refB"替换为"私有B refB".但这样做可以更容易规避某些安全措施.

这是可能的还是我必须在RawSql中添加所有属性?

bie*_*ior 5

在Ebean中过滤是出于其他目的,而不仅仅是操纵该WHERE子句,在其他问题中查看比较.

在这里你有一个正确的方法(我改变模型,以显示完整,工作样本)

楷模

@Entity
public class A extends Model {

    @Id
    public Integer id;

    @ManyToOne
    public B b;

    public static Finder<Integer, A> find
                = new Finder<Integer, A>(Integer.class, A.class);

}

@Entity
public class B extends Model {

    @Id
    public Integer id;
    public Boolean hidden;

    public static Finder<Integer, B> find
            = new Finder<Integer, B>(Integer.class, B.class);

}
Run Code Online (Sandbox Code Playgroud)

调节器

public static Result index() {

    // Insert some data one every request
    B bFalse = new B();
    bFalse.hidden = false;
    bFalse.save();

    B bTrue = new B();
    bTrue.hidden = true;
    bTrue.save();

    A a1 = new A();
    a1.b = bFalse;
    a1.save();

    A a2 = new A();
    a2.b = bTrue;
    a2.save();

    A a3 = new A();
    a3.b = bTrue;
    a3.save();

    // Let's search...
    List<A> aListOfNotHidden = A.find.where().and(Expr.eq("b.hidden", false), Expr.isNotNull("b.hidden")).findList();
    for (A a : aListOfNotHidden) {
        Logger.info("NOT hidden " + a.id);
    }

    List<A> aListOfHidden = A.find.where().eq("b.hidden", true).findList();
    for (A a : aListOfHidden) {
        Logger.warn("HIDDEN " + a.id);
    }

    return ok("check logs in your console");
}
Run Code Online (Sandbox Code Playgroud)

结果H2的SQL

-- all NOT hidden
select t0.id c0, t0.b_id c1
from a t0
left outer join b t1 on t1.id = t0.b_id
where (t1.hidden = false  and t1.hidden is not null ) 

-- all hiden
select t0.id c0, t0.b_id c1 
from a t0
left outer join b t1 on t1.id = t0.b_id  
where t1.hidden = true 
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用SqlQuery仅获取SqlRows(而不是对象)检查链接API以获取使用示例,设置命名参数等:

List<SqlRow> rows = Ebean.createSqlQuery("select t0.*  " +
        "from a t0 left outer join b t1 on t1.id = t0.b_id " +
        "where (t1.hidden = false  and t1.hidden is not null ) ").findList();


for (SqlRow row : rows) {
    // do something with each row here, use methods such 
    // as getString("fieldname") for retrieving data  
    // (from SqlRow API)
}
Run Code Online (Sandbox Code Playgroud)