【问题标题】:Select and order list by other condition(Criteria inner join hibernate)按其他条件选择和排序列表(条件内连接休眠)
【发布时间】:2018-05-28 10:19:07
【问题描述】:

假设我们使用以下 SQL 创建 2 个表:

create table Supplier (id int, name VARCHAR, count int);
create table Product (id int, name VARCHAR, description VARCHAR, price double, supplierId int);

型号:

公共类供应商{

private int id;

private String name;
private int count;

public int getId(){   return id;}
public void setId(int id){     this.id = id; }

public String getName(){   return name;}
public void setName(String name){    this.name = name;}

public int getCount() {    return count;}
public void setCount(int count) {   this.count = count;}

}

public class Product {

private int id;
private String name;
private String description;
private Double price;
private Supplier supplier;

public int getId() {    return id;}
public void setId(int id) {   this.id = id; }

public String getName() {    return name;}
public void setName(String name) {   this.name = name;}

public String getDescription() {    return description;}
public void setDescription(String description) {    this.description = description; }

public Double getPrice() {return price;}
public void setPrice(Double price) {   this.price = price;}

@OneToOne(targetEntity=ProductAssignment.class, mappedBy = "supplierId", fetch = FetchType.LAZY)
public Supplier getSupplier() {    return supplier;}
public void setSupplier(Supplier supplier) {    this.supplier = supplier; }

}

如果我想按供应商数量选择所有产品订单,我可以使用以下代码:

Criteria crit = session.createCriteria(Product.class);
Criteria critSupplier = crit.createCriteria("supplier");
critSupplier.addOrder(Order.desc("count"));

但是现在,我想在产品表中按价格选择所有供应商订单。

如果我想使用 MySQL,下面是脚本: select * from supplier s inner join product p ON s.id = p.supplierId order by p.price

现在我想将这个 SQL 转换为 java 代码中的 Hibernate Criteria 查询?

在这种情况下请帮助我吗?

【问题讨论】:

    标签: java mysql hibernate criteria


    【解决方案1】:

    这里有两个模型之间的双向关系:供应商和产品。这是一种双向关系,因为您希望两个模型彼此了解,并根据连接它们的链接 (supplierId) 重新收集彼此的信息。这种关系也是一个(供应商)对多(产品)的关系

    因此,首先,您错过了供应商也必须意识到关系存在的事实。您必须通过修改 Supplier 模型并向其中添加产品列表来表达这种“意识”:

    public class Supplier implements Serializable{
        private int id;
        private String name;
        private int count;
        private List<Product> products;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public List<Product> getProducts() {
            return products;
        }
    
        public void setProducts(List<Product> products) {
            this.products = products;
        }
    
        @Override
        public String toString() {
            return "Supplier{" + "name=" + name + '}';
        }
    

    第二步是在 ORM(在您的情况下为休眠)传达两个模型之间的关系。在线您可以找到大量解释休眠的这个微妙“步骤”的文档。在你的情况下,应该这样做。

    供应商的休眠映射:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.xxx.stackoverflowdb.model.Supplier" table="Supplier">
            <id column="id" name="id" type="int">
                <generator class="assigned"/>
            </id>
            <property column="name" name="name" type="string"/>
            <property column="count" name="count" type="int"/>
            <bag name="products" table="product" inverse="true" lazy="false" fetch="select">
                <key>
                    <column name="id"/>
                </key>
                <one-to-many class="com.xxx.stackoverflowdb.model.Product"/>
            </bag>
        </class>
    </hibernate-mapping>
    

    产品的休眠映射:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.xxx.stackoverflowdb.model.Product" table="PRODUCT">
            <id column="id" name="id" type="int">
                <generator class="assigned"/>
            </id>
            <property column="name" name="name" type="string"/>
            <property column="description" name="description" type="string"/>
            <property column="price" name="price" type="double"/>
            <many-to-one name="supplierId" class="com.xxx.stackoverflowdb.model.Supplier" column="supplierId" insert="false" update="false" lazy="false"/>
        </class>
    </hibernate-mapping>
    

    如您所见,两个映射文件都声明了关系。有了这套,您可以编写标准并让它完成工作。由于它现在 hibernate 知道这种关系,它可以帮助你。我创建了一个简单的测试器类来演示它:

    public class Tester {
    public static void main(String[] args) {
    
        //gets a session, assuming your cg file is in a folder called hibernate_dispatcher 
        //under classpath
        SessionFactory sessionFactory = new Configuration().configure("/hibernate_dispatcher/hibernate.cfg.xml")
                                     .buildSessionFactory();
        Session session = sessionFactory.openSession();
        //gets a session, assuming your cg file is in a folder called hibernate_dispatcher 
        //under classpath
    
    
        //YOUR own query --> gets all products order by count in supplier
        Criteria criteria1 = session.createCriteria(Product.class);
        criteria1.createAlias("supplierId", "supp");
        criteria1.addOrder(Order.desc("supp.count"));
    
        for(Object p:criteria1.list()){
            Product nthP=(Product)p;
            System.out.println(nthP);
        }
        //YOUR own query --> gets all products order by count in supplier
    
    
    
        //the query you've asked --> gets all products order by price in Product
        Criteria criteria2 = session.createCriteria(Supplier.class);
        criteria2.createAlias("products", "prod");
        criteria2.addOrder(Order.desc("prod.price"));
    
        for(Object s:criteria2.list()){
            Supplier nthS=(Supplier)s;
            System.out.println(nthS);
        }
        //the query you've asked --> gets all products order by price in Product
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      • 1970-01-01
      • 2011-07-03
      相关资源
      最近更新 更多