Select 并按其他条件排序列表(Criteria inner join hibernate)
Select and order list by other condition(Criteria inner join hibernate)
假设我们创建 2 tables 如下 SQL :
create table Supplier (id int, name VARCHAR, count int);
create table Product (id int, name VARCHAR, description VARCHAR, price double, supplierId int);
型号:
public class 供应商 {
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; }
}
如果我想 select 按供应商数量订购所有产品,我可以使用以下代码:
Criteria crit = session.createCriteria(Product.class);
Criteria critSupplier = crit.createCriteria("supplier");
critSupplier.addOrder(Order.desc("count"));
但是现在,我想 select 所有供应商按产品 table 中的价格订购。
如果我想使用MySQL,下面是脚本:
select * from supplier s inner join product p ON s.id = p.supplierId order by p.price
现在我想将此 SQL 转移到 java 代码中的 Hibernate Criteria 查询中吗?
这种情况请帮帮我?
这里有两个模型之间的双向关系:供应商和产品。这是一种双向关系,因为您希望两个模型相互了解,并根据连接它们的 link (supplierId) 相互收集信息。关系也是one(Supplier)-toMany(Products)
所以,首先,您忽略了一个事实,即供应商也必须知道这种关系的存在。您必须通过修改 Supplier 模型并向其添加列表产品来表达此 "awareness":
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(在您的情况下是休眠)两个模型之间的关系。您可以在网上找到大量文档来解释休眠的这种微妙 "step"。在你的情况下,应该这样做。
供应商的 Hibernate 映射:
<?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.Whosebugdb.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.Whosebugdb.model.Product"/>
</bag>
</class>
</hibernate-mapping>
产品的 Hibernate 映射:
<?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.Whosebugdb.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.Whosebugdb.model.Supplier" column="supplierId" insert="false" update="false" lazy="false"/>
</class>
</hibernate-mapping>
如您所见,两个映射文件都声明了关系。使用此集合,您可以编写标准并让它完成工作。因为它现在休眠知道这种关系,所以它可以帮助你。我创建了一个简单的测试器 class 来演示它:
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
}
}
假设我们创建 2 tables 如下 SQL :
create table Supplier (id int, name VARCHAR, count int);
create table Product (id int, name VARCHAR, description VARCHAR, price double, supplierId int);
型号:
public class 供应商 {
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; }
}
如果我想 select 按供应商数量订购所有产品,我可以使用以下代码:
Criteria crit = session.createCriteria(Product.class);
Criteria critSupplier = crit.createCriteria("supplier");
critSupplier.addOrder(Order.desc("count"));
但是现在,我想 select 所有供应商按产品 table 中的价格订购。
如果我想使用MySQL,下面是脚本:
select * from supplier s inner join product p ON s.id = p.supplierId order by p.price
现在我想将此 SQL 转移到 java 代码中的 Hibernate Criteria 查询中吗?
这种情况请帮帮我?
这里有两个模型之间的双向关系:供应商和产品。这是一种双向关系,因为您希望两个模型相互了解,并根据连接它们的 link (supplierId) 相互收集信息。关系也是one(Supplier)-toMany(Products)
所以,首先,您忽略了一个事实,即供应商也必须知道这种关系的存在。您必须通过修改 Supplier 模型并向其添加列表产品来表达此 "awareness":
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(在您的情况下是休眠)两个模型之间的关系。您可以在网上找到大量文档来解释休眠的这种微妙 "step"。在你的情况下,应该这样做。
供应商的 Hibernate 映射:
<?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.Whosebugdb.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.Whosebugdb.model.Product"/>
</bag>
</class>
</hibernate-mapping>
产品的 Hibernate 映射:
<?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.Whosebugdb.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.Whosebugdb.model.Supplier" column="supplierId" insert="false" update="false" lazy="false"/>
</class>
</hibernate-mapping>
如您所见,两个映射文件都声明了关系。使用此集合,您可以编写标准并让它完成工作。因为它现在休眠知道这种关系,所以它可以帮助你。我创建了一个简单的测试器 class 来演示它:
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
}
}