Dan*_*Dan 18 java hibernate inner-join
我似乎在使用hibernate中的查询时遇到了一些困难.我正在两个表上执行内连接.
SELECT * FROM product p INNER JOIN warehouse w ON p.wid = w.id
Run Code Online (Sandbox Code Playgroud)
产品表:
id | name | wid | price | stock .....
Run Code Online (Sandbox Code Playgroud)
仓库表:
id | name | city | lat | long .....
Run Code Online (Sandbox Code Playgroud)
加入结果:
id | name | wid | price | stock | id | name | city | lat | long .....
Run Code Online (Sandbox Code Playgroud)
当我运行查询..
Session.createSQLQuery(this.query)
.addEntity("p", Product.class)
.addEntity("w", Warehouse.class).list();
Run Code Online (Sandbox Code Playgroud)
因此,对于每个结果,我得到一个包含a Product object和a 的对象Warehouse object.
这是预料之中的.问题是hibernate将产品的id和名称分配给仓库对象id和name属性.就创建Warehouse项目而言,好像连接结果中的前两列都过度了.Product对象始终包含正确的数据.
关于找到解决此问题的方法的任何建议,以便表示正确仓库数据的id和name列将非常受欢迎.
提前致谢.
使用{}表单可以避免列名重复出现问题:
SELECT {p.*}, {w.*} FROM product p INNER JOIN warehouse w ON p.wid = w.id
Run Code Online (Sandbox Code Playgroud)
从 Hibernate参考文档,第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)
Run Code Online (Sandbox Code Playgroud)
该查询旨在每行返回两个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)
Run Code Online (Sandbox Code Playgroud)
此查询指定:
SQL查询字符串,其中包含占位让Hibernate注射字段别名由查询返回的实体
{cat.*}和{mother.*}符号上面使用的是"所有属性"的简写.
如果实体不是来自同一个类,那么这是一个示例:
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();
}
Run Code Online (Sandbox Code Playgroud)
正如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]);
... }
Run Code Online (Sandbox Code Playgroud)