我似乎对hibernate中的查询有些困难。我在两个表上执行内连接。
SELECT * FROM product p INNER JOIN warehouse w ON p.wid = w.id
产品表:
id | name | wid | price | stock .....
仓库表:
id | name | city | lat | long .....
加入结果:
id | name | wid | price | stock | id | name | city | lat | long .....
当我运行查询时..
Session.createSQLQuery(this.query)
.addEntity("p", Product.class)
.addEntity("w", Warehouse.class).list();
因此,对于每个结果,我都会得到一个包含Product object
和Warehouse object
的对象。
这是预期的。问题是hibernate将产品的id和名称分配给仓库对象id和name属性。就创建Warehouse项目而言,好像连接结果中的前两列都过度了。 Product对象始终包含正确的数据。
有关找到解决此问题的方法的任何建议,因此非常感谢表示正确仓库数据的ID和名称列。
提前致谢。
答案 0 :(得分:9)
使用{}表单可以避免列名重复出现问题:
SELECT {p.*}, {w.*} FROM product p INNER JOIN warehouse w ON p.wid = w.id
来自Hibernate Reference Documentation,第18.1.4节。返回多个实体:
到目前为止,结果集列名称假定与之相同 映射文档中指定的列名称。这可以 对于连接多个表的SQL查询存在问题,因为相同 列名称可以出现在多个表中。
以下查询中需要列别名注入(大多数情况下都是如此) 可能会失败):
sess.createSQLQuery("SELECT c.*, m.* FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class)
该查询旨在每行返回两个Cat实例:一只猫和一只猫 它的母亲。但是,查询将失败,因为存在冲突 名字;实例映射到相同的列名称。还有,开 一些数据库中返回的列别名最有可能出现在 表格“c.ID”,“c.NAME”等不等于列 在映射中指定(“ID”和“NAME”)。
以下表单不容易受到列名重复的影响:
sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class)
此查询指定:
SQL查询字符串,带有占位符,用于Hibernate注入列 别名查询返回的实体
{cat.*}
和 上面使用的{mother.*}
符号是“所有属性”的简写。
答案 1 :(得分:6)
如果实体不是来自同一个类,那么这是一个示例:
public static void main(String[] args) {
Session sess = NewHibernateUtil.getSessionFactory().openSession();
SQLQuery q = null;
String query = "select a.*, u.* from user u, account a where a.iduser=u.iduser";
q = sess.createSQLQuery(query);
q.addEntity(User.class);
q.addEntity(Account.class);
List lst = q.list();
System.out.println("" + lst.size());
for (int i = 0; i < lst.size(); i++) {
System.out.println(((Object[]) lst.get(i))[0]); //account bean, actually this is in reverse order - so this is user bean
System.out.println(((Object[]) lst.get(i))[1]); //user bean & this account bean
}
sess.close();
}
答案 2 :(得分:6)
正如coding_idiot所说,也许您不知道查询结果的实体,因为它们来自不同的类,您可以访问元素中的每个对象。
List<Object>
以检索查询结果(示例:
List<Object> objs = (List<Object>)query.getResultList();
)for (Object obj : objs){...}
)List<Object>
的每个元素都有Object[]
将每个元素强制转换为此类(例如:Object[] o = (Object[]) obj;
)o[4]
)代码示例:
Query query = JPA.em().createNativeQuery("SELECT * FROM product p
INNER JOIN warehouse w ON p.wid = w.id");
/* I suppose that it return fields sorted by entities and field in
database:
*
* 0: product.id | 1: product.name | 2: product.wid | 3: product.price | 4: product.stock | n-1: product.N-1Field
* n: warehouse.id | n+1: name | n+2: warehouse.city | n+3: warehouse.lat | n+4: warehouse.long | m-1: warehouse.M-1Field
*
* Join result: id | name | wid | price | stock | ... | id | name | city | lat | long | ...
*/
List<Object> objs = (List<Object>)query.getResultList();
for (Object obj : objs) {
Object[] o = (Object[]) obj;
String productId = String.valueOf(o[0]);
String productName = String.valueOf(o[1]);
String productWid = String.valueOf(o[2]);
... }