我有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中的似乎没有工作。
答案 0 :(得分:1)
可以在hibernate(JPA)中连接任意数量的表。如何返回数据取决于业务需求的需求。
在您的示例中,您似乎正在利用StringBuilder / StringBuffer创建本机SQL查询,对吧?这不需要,不过。在大多数情况下没用。
通常应用hibernate来返回映射的实体,换句话说,表示数据库表数据的Java对象。然后,您可以使用当前持久化上下文中的访问器和更改器(getter和setter)来处理此对象,甚至可以处于分离状态。
使用hibernate映射,您可以定义关系,允许您通过Java方法调用浏览图形来访问所有已分配的对象。
也许看看here。
但是假设您使用ORM层的功能来访问数据,这意味着在Session / EntityManager对象上调用实体查询(访问方法),HQL / JPQL查询或使用Criteria API。
想象一下,你会有一个映射,它可以完全写出一个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对象。