有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用criteriabuilder构建带有treat的类型安全选择

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

@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中的同一列

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


共 (1) 个答案

  1. # 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