使用criteriabuilder构建类型安全选择with treat

时间:2017-08-21 06:09:07

标签: java hibernate jpa

我有一个表的基本抽象类,抽象类没有保留所有列

@Entity
@Table(name = "MYTABLE")
public abstract class MyTable {
    //...
}

通常我会在criteriabuilder

中使用treat从其派生类中获取所需的列数据
@Entity
public class MyClassA extends MyTable {
    //...
}
@Entity
public class MyClassB extends MyTable {
    //...
}

Root<MyTable> myTable = cq.from(MyTable.class);
cq.where(cb.or(
    cb.equal(cb.treat(myTable, MyClassA.class).get(MyClassA_.infoA), "A"),
    cb.equal(cb.treat(myTable, MyClassB.class).get(MyClassB_.infoB), "B")
))

这里infoA和infoB都是数据库中MYTABLE中的相同列。

我的问题是你如何编写一个类型安全的选择来在一个选择中同时选择infoA和infoB?

1 个答案:

答案 0 :(得分:0)

我不确定,如果有真正的理由不将infoA和infoB变量同时移动到基类中,正如OO原则所示,因为它简化了所有内容。

但是如果你无意中做到了,我建议做一些小的重构,并使用继承映射和ORM框架提供的所有好处:

@Entity
public abstract class MyTable {

    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long Id;

    private String info;

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public Long getId() {
       return Id;
    }

    public void setId(Long id) {
       Id = id;
    }
}

@Entity
public class MyClassA extends MyTable {
    //...
}
@Entity
public class MyClassB extends MyTable {
    //...
}

这样你就可以多态地查询你的MyClassA和MyClassB:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<MyTable> query = builder.createQuery( MyTable.class );
        Root<MyTable> root = query.from( MyTable.class );
        query.select( root );
        List<MyTable> entities = entityManager.createQuery( query ).getResultList();

如果是Hibernate,请查看以下内容:

http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#entity-inheritance