如何在Hibernate中连接多个表?

时间:2016-12-27 11:32:37

标签: java mysql hibernate join

我有4个表CustomerEntity,CustomerMaster,Request和UserMaster
  并具有以下表格结构,

CustomerEntity  (id,address,branch,branch_id,city,entity_status,request_id,user_master_id)
CustomerMaster (id,customer_name,customer_type)  
UserMaster(id,customer_master_id,employee_id,unique_id,employee_id)  
Request(id,customer_master_id,parent_request_id,request_status,user_master_id)

当我像这样从Hibernate进行查询时

sb.append("select c from CustomerEntity c, Request r ") 

它为我提供了我需要的正确数据,但现在有一种情况我需要捕获UserMaster id以及CustomerMaster id值,这只能通过将UserMaster和CustomerMaster表与现有值一起获取来获取查询,但我不知道我将在何处获得所有投影数据,如上述查询中所示,我将获取数据' c'但在新查询中,我希望在加入所有这4个表后执行查询中的所有值。

我使用以下查询:

sb.append("select * from  (CustomerEntity as c join Request as r
  on r.id = c.request_id)
  left join  CustomerMaster as c1 on r.customer_master_id = c1.id 
  left join UserMaster as u
  on r.customer_master_id = u.customer_master_id");
像这样在Hibernate中的

似乎没有工作。

1 个答案:

答案 0 :(得分:1)

可以在hibernate(JPA)中连接任意数量的表。如何返回数据取决于业务需求的需求。

在您的示例中,您似乎正在利用StringBuilder / StringBuffer创建本机SQL查询,对吧?这不需要,不过。在大多数情况下没用。

通常应用hibernate来返回映射的实体,换句话说,表示数据库表数据的Java对象。然后,您可以使用当前持久化上下文中的访问器和更改器(getter和setter)来处理此对象,甚至可以处于分离状态。

使用hibernate映射,您可以定义关系,允许您通过Java方法调用浏览图形来访问所有已分配的对象。

也许看看here

但是假设您使用ORM层的功能来访问数据,这意味着在Session / EntityManager对象上调用实体查询(访问方法),HQL / JPQL查询或使用Criteria API。

Thisthis应该会为您提供更多信息。

想象一下,你会有一个映射,它可以完全写出一个HQL查询,例如: const protobuf = require('protobufjs'); const protoFile = __dirname + '/testAnyProto.proto'; function AnyMessageType(properties) { protobuf.Message.call(this, properties); // call the super constructor } var root = protobuf.loadSync(protoFile); protobuf.Class.create(root.lookup('google.protobuf.Any'), AnyMessageType); var sampleBuffer = new Buffer('ABCDEF', 'utf8'); var sampleAny = new AnyMessageType({ type_url: "some.type", value: sampleBuffer }); var sampleAnyEncodedBuffer = AnyMessageType.encode(sampleAny).finish(); var sampleAnyEncodedDecoded = AnyMessageType.decode(sampleAnyEncodedBuffer); //just checking if I am getting back 'ABCDEF' and... I am console.log(sampleAnyEncodedDecoded.value.toString('utf8')); var TestMessageType = root.lookup('myTest.TestMessage'); // Create a new message var testMessage = TestMessageType.create({ message: 'Some message', details: sampleAny //??? when I decode a testMessage, it creates an AnyMessageType, so I assume I am right }); var encodedTestMessage = TestMessageType.encode(testMessage).finish(); var decodedEncodedTestMessage = TestMessageType.decode(encodedTestMessage); console.log(decodedEncodedTestMessage.details.value.toString('utf8')); 将返回单个实体。通过其访问器,您可以浏览图表。

也可以在HQL中编写联接,在这种情况下,您只需要告诉哪些实体应该像SELECT c FROM CustomerEntity AS c一样加入,并且您可以在常规情况下省略SELECT c FROM CustomerEntity AS c JOIN c.request AS r ...子句。由于映射,Hibernate知道实体是如何连接的。

当然,在获取适当数量的数据(渴望与懒惰)时,您的映射应该得到充分考虑。 (单向与双向)。在某些情况下,编写针对您的用例定制的查询甚至比通过Java方法导航以避免性能损失更好,但这是您必须根据数据结构和数据大小来决定的。

最后但同样重要的是,如果需要,您也可以使用native SQL queries,但是您必须自己关注将其映射到Java对象。