【问题标题】:Using criteriabuilder to build type safe select with treat使用标准构建器构建类型安全选择和处理
【发布时间】:2017-08-21 06:09:07
【问题描述】:

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

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

通常我在标准构建器中使用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?

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    我不确定是否有真正的理由不将 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

    【讨论】:

    • 谢谢。我也不知道原因,那不是我的代码。但是假设我必须使用此代码,如何在结果中选择 infoA 和 infoB 作为单个列?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多