为什么hibernate为了加载@OneToOne双向关联而执行两个查询?(Why hibernate perform two queries for eager load a @OneToOne bidirectional association?)
我有实体A有一个B实体,B有一个带有@OneToOne双向关联的A。
现在,当我找到A记录时,hibernate用B上的左外连接执行两个查询,如下所示:
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b; select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?
首先查询加载A和B字段,这是可以的,但为什么执行第二个查询来重新加载A? 我认为这个查询加载了B中的A内容,但是这个A很明显是包含B的A ...因此它已经加载了第一个查询,是不是真的?
- 编辑 -
实体A:
@Entity public class A implements Serializable{ // id and other ecc ecc @OneToOne @JoinColumn(name="id_b") B b; }
实体B:
@Entity public class B implements Serializable{ // id and other ecc ecc @OneToOne(mappedBy="b") A a; }
情况就是这样,findAll on A需要两个查询......为什么?
i have entity A that has-a B entity, and B has-a A with @OneToOne bidirectional association.
Now, when i findall A records, hibernate perform two queries with a left outer join on B, something like this:
select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b; select a.id, a.id_b, a.field1, b.id, b.field1 from A as a, B as b left outer join b ON b.id=a.id_b WHERE b.id=?
First query load A and B fields and it is ok, but why perform second query to reload A? I think this query load the A content in B, but this A is obviusly the A that contains B... so its already loaded with first query, isn't true?
-- EDIT --
Entity A:
@Entity public class A implements Serializable{ // id and other ecc ecc @OneToOne @JoinColumn(name="id_b") B b; }
Entity B:
@Entity public class B implements Serializable{ // id and other ecc ecc @OneToOne(mappedBy="b") A a; }
This is the situation, and a findAll on A need two queries... why?
原文:https://stackoverflow.com/questions/3381521
最满意答案
有两种使用TSQL选择BLOB的方法:
SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
以及:
SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
请注意FROM子句之后的相关名称,这是强制性的。
第二个版本可以用于UPDATE,如下例所示:
UPDATE MyTable SET blobField = (SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a) WHERE (CriteriaField = @criteria)
对于部分更新,可以使用此MSDN文章中所述的SET .WRITE增变器,这里是语法:
UPDATE MyTable SET BlobField .WRITE (expression, @offset, @length) WHERE (CriteriaField = @criteria)
请注意,WRITE mutator只能用于NON-NULL字段。
事实上,通过将@offset设置为0并将@length设置为NULL(或实际长度),也可以将其用于执行完整更新(如果列不包含NULL),如下例所示:
DECLARE @tmp VARBINARY(MAX) --Change to the correct datatype here SELECT @tmp = BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a UPDATE MyTable SET BlobField .WRITE (@tmp, 0, NULL) WHERE (CriteriaField = @criteria)
There are two ways to SELECT a BLOB with TSQL:
SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
As well as:
SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a
Note the correlation name after the FROM clause, which is mandatory.
The second version can be used for a UPDATE as in the following example:
UPDATE MyTable SET blobField = (SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a) WHERE (CriteriaField = @criteria)
For partial updates one can use the SET .WRITE mutator as described in this MSDN article, here is the syntax:
UPDATE MyTable SET BlobField .WRITE (expression, @offset, @length) WHERE (CriteriaField = @criteria)
Note that the WRITE mutator can only be used on NON-NULL fields.
In fact this can also be used to do a full update (if the column does not contain NULL), by setting @offset to 0 and @length to NULL (or to the actual length), as in the following example:
DECLARE @tmp VARBINARY(MAX) --Change to the correct datatype here SELECT @tmp = BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a UPDATE MyTable SET BlobField .WRITE (@tmp, 0, NULL) WHERE (CriteriaField = @criteria)
相关问答
更多-
有两种使用TSQL选择BLOB的方法: SELECT * FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a 以及: SELECT BulkColumn FROM OPENROWSET (BULK 'C:\Test\Test1.pdf', SINGLE_BLOB) a 请注意FROM子句之后的相关名称,这是强制性的。 第二个版本可以用于UPDATE,如下例所示: UPDATE MyTable SET blobField = (SE ...
-
只要LittleTable满足作为OUTPUT ... INTO目标的要求,就可以使用OUTPUT子句 UPDATE BigTable SET ExportedFlag = 'T' OUTPUT inserted.Col1, inserted.Col2 INTO LittleTable(Col1,Col2) WHERE
如果您使用INSERTED或DELETED ,则没有任何区别。 唯一不同的列是你正在更新的那个(已deleted.ExportedFlag具有之前的值并且i ... -
tsql用哪里更新(tsql Update with where)[2023-02-18]
您可以使用带有JOIN UPDATE执行此操作。 像这样的东西: UPDATE t1 SET t1.Grouped = t2.Grouped FROM @WorkTable t1 INNER JOIN @Worktable t2 ON -- a condition WHERE -- you can also add conditions here You can do this using UPDATE with JOIN. Something like this: UPDATE t1 SET t1.Gr ... -
UPDATE m SET m.name = m1.name FROM MyTable m JOIN MyTable1 m1 ON m.id = m1.id WHERE m.id = 1 UPDATE m SET m.name = m1.name FROM MyTable m JOIN MyTable1 m1 ON m.id = m1.id WHERE m.id = 1
-
我在执行我的程序时遇到同样的问题。 Windows 2012和Windows 2007之间的MSXML2.HTTP方法似乎有所不同。例如,2012年发送的工作方式如下: DECLARE @send NVARCHAR(4000) = 'send("' + REPLACE(@requestBody, '"', '''') + '")'; EXEC @hResult = sp_OAMethod @objectID, @send 不像 sp_OAMethod @objectID, 'send', null, @ ...
-
这应该接近你需要的。 可能需要处理连接条件,但我认为我从INSTR的转换将会这样做。 UPDATE i SET strFileProcesstype = fs.STRFILEPROCESSTYPE, strFileSignatureType = fs.strfilesignaturetype FROM tblitem i INNER JOIN tblFileSignature fs ON i.strfilesignature = LE ...
-
从TSQL检测Sql Express(Detect Sql Express From TSQL)[2024-04-26]
有几种方法: EXEC sp_server_info 2 要么 SELECT @@version 要么 SELECT serverproperty('ProductVersion') 你也可以这样做: DECLARE @ver nvarchar(128) SET @ver = CAST(serverproperty('ProductVersion') AS nvarchar) SET @ver = SUBSTRING(@ver, 1, CHARINDEX('.', @ver) - 1) IF ( @v ... -
澄清 - 使用更新TSQL(Clarification - Using Update TSQL)[2023-05-22]
这是SQL Server中数据类型优先的经典案例。 Int始终具有比varchar更高的优先级。 你的第一个座位 在第一个块的update语句中,即使CASE语句的一个结果表达式具有int数据类型(在本例中为@passState),并且CASE语句的其余结果表达式求值为varchar数据类型,那么结果所有的表达式都应该是Int,因为Int优先于varchar。 但是,当CASE的其余结果表达式求值为varchar时,您将在第一个CASE结果表达式@passFName上获得语法错误,因为它期望为所有的int: ... -
SELECT D.DiscountID FROM Discounts D LEFT JOIN TeamExclusiveDiscount T ON D.DiscountID=T.DiscountID WHERE T.TeamID=@TeamID OR T.TeamID IS NULL SQL测试的SQLFIDDLE SELECT D.DiscountID FROM Discounts D LEFT JOIN TeamExclusiveDiscount T ON D.Disc ...
-
SQL Server TSQL - 如何在CASE中实现“NOT IN”语句(SQL Server TSQL - How to achieve “NOT IN” statements within a CASE)[2022-04-01]
CASE语句返回一个值,它不通过更改SQL查询充当IF语句(如果是,则执行此操作)。 您需要将where语句修改为以下内容: AND ( (@status = 99 AND v.idStatus NOT IN (5, 1, 4, 20)) OR (@status NOT IN (0, 99) AND v.idStatus = @status) ) 编辑:评论者是正确的,第二次检查需要确保@status不是99。 The CASE statement returns a ...