繁体   English   中英

通过其他条件选择和排序列表(条件内部联接休眠)

[英]Select and order list by other condition(Criteria inner join hibernate)

假设我们用下面的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查询吗?

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

在这里,您可以在两个模型之间建立双向关系:供应商和产品。 这是一种双向关系,因为您希望两个模型都能够相互了解,并基于连接它们的链接(supplierId)相互收集彼此的信息。 该关系也是一对(供应商)对多(产品)

因此,首先,您会错过一个事实,那就是供应商也必须意识到该关系的存在。 您必须通过修改供应商模型并将其添加到清单产品中来表达这种“意识”:

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>

如您所见,两个映射文件都声明了该关系。 有了这个设置,您可以编写条件并让它完成任务。 由于它现在冬眠了解这种关系,因此可以为您提供帮助。 我创建了一个简单的测试器类来演示它:

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
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM