问题描述
+ ----- 我有一张我正在使用的旧表格,它看起来像这样: ------------- + -------------- + ------ + ----- + -------- - + ------- +
|字段|类型|空| Key |默认|额外|
+ ------------------ + -------------- + ------ + ---- - + --------- + ------- +
| BINARY_DATA_ID | varchar(255)| NO | PRI | | |
| BINARY_DATA | longblob |是| | NULL | |
| BINARY_DATA_NAME | varchar(255)|是| | NULL | |
+ ------------------ + -------------- + ------ + ---- - + --------- + ------- +
主要的问题在于 BinaryData
Java类加载了 BINARY_DATA
列,即使我只需要 BINARY_DATA_NAME
。我知道构建这个最好的方法是将数据从元数据中分离出来(比如文件名),以便它们存在于不同的表中。从那里数据延迟加载是微不足道的。这是本该如何完成的。
不幸的是,由于组织的限制,我可能无法做到以上几点。作为一种解决方法,是否可以使用一些注释来使该列延迟加载,而不是将事件拆分为单独的表?我修改了 BinaryData
类,以便它有一个内部静态 BinaryDataData
类,它是 @Embedded
和属性是 @Basic(fetch = FetchType.LAZY)
:
<$
@Table
@Proxy(lazy = false)
@Inheritance(strategy = InheritanceType.JOINED)
public class BinaryData implements Serializable,Persistable< BinaryData> ;, Cloneable {
private static final long serialVersionUID = / ** blah * /;
@Id @Column @GeneratedValue(generator =uuid)@GenericGenerator(name =uuid,strategy =uuid)
private String id;
@Column
private String binaryDataName;
@Embedded
@Basic(fetch = FetchType.LAZY)
private BinaryDataData binaryData;
@Transient
private String cacheId;
$ b $ / **
* Hibernate构造函数
* /
public BinaryData(){/ *创建一个新的Attachment实例。 * /}
public BinaryData(byte [] binaryData,String binaryDataName){
this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData));
this.binaryDataName = binaryDataName;
}
/ **
*返回BinaryData字节流。
*
* @return binaryData字节流
* /
@Embedded
@Basic(fetch = FetchType.LAZY)
public byte [] getBinaryData( ){
if(this.binaryData == null){
return new byte [0];
}
return binaryData.getActualData();
$ b @Embeddable
public static class BinaryDataData implements Serializable {
@Column(length = 32 * 1024 * 1024,columnDefinition =longblob,name = BINARY_DATA)@Lob
private byte [] actualData;
public BinaryDataData(){}
$ b $ public BinaryDataData(byte [] data){
this.actualData = data;
$ b $ public byte [] getActualData(){
if(this.actualData == null){
return new byte [0];
}
返回this.actualData;
}
public void setBinaryData(byte [] newData){
this.actualData = newData;
@Override public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(!(obj instanceof BinaryDataData)){
return false;
}
final BinaryDataData other =(BinaryDataData)obj;
if(!Arrays.equals(actualData,other.actualData)){
return false;
}
返回true;
}
}
/ **向前... * /
不幸的是,这不起作用。即使未请求二进制数据,我所看到的SQL仍会显示对象的完整提取:
select ideaattach0_.BINARY_DATA_ID如BINARY1_9_,ideaattach0_1_.BINARY_DATA如BINARY2_9_,ideaattach0_1_.BINARY_DATA_NAME如BINARY3_9_,ideaattach0_.IDEA_BUCKET_ID如IDEA2_136_从IDEA_ATTACHMENT ideaattach0_内部联接上ideaattach0_.BINARY_DATA_ID = ideaattach0_1_.BINARY_DATA_ID其中ideaattach0_.BINARY_DATA_ID = BINARY_DATA ideaattach0_1_?
有什么想法?谢谢。
From :
I have an old table that I'm working with, which looks like this:
+------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| BINARY_DATA_ID | varchar(255) | NO | PRI | | |
| BINARY_DATA | longblob | YES | | NULL | |
| BINARY_DATA_NAME | varchar(255) | YES | | NULL | |
+------------------+--------------+------+-----+---------+-------+
The main problem with this is that the BinaryData
Java class loads the BINARY_DATA
column, even if I only require the BINARY_DATA_NAME
. I know that the best way to architect this is to split the data from the meta-data (like the file name) so they live in separate tables. From there it's trivial to make the data lazy-loaded. This is how it should have been done in the first place.
Unfortunately it may not be possible for me to do the above due to organizational constraints. As a workaround, is it possible to make that column lazy-loaded using some annotations instead of splitting things out into separate tables? I've modified the BinaryData
class so that it has an inner static BinaryDataData
class which is @Embedded
and the attribute is @Basic(fetch=FetchType.LAZY)
:
@Entity
@Table
@Proxy(lazy=false)
@Inheritance(strategy=InheritanceType.JOINED)
public class BinaryData implements Serializable, Persistable<BinaryData>, Cloneable {
private static final long serialVersionUID = /** blah */;
@Id @Column @GeneratedValue(generator="uuid") @GenericGenerator(name="uuid", strategy="uuid")
private String id;
@Column
private String binaryDataName;
@Embedded
@Basic(fetch = FetchType.LAZY)
private BinaryDataData binaryData;
@Transient
private String cacheId;
/**
* Hibernate constructor
*/
public BinaryData() { /* Creates a new instance of Attachment. */}
public BinaryData(byte[] binaryData, String binaryDataName) {
this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData));
this.binaryDataName = binaryDataName;
}
/**
* Returns the BinaryData byte stream.
*
* @return binaryData byte stream
*/
@Embedded
@Basic(fetch = FetchType.LAZY)
public byte[] getBinaryData() {
if (this.binaryData == null) {
return new byte[0];
}
return binaryData.getActualData();
}
@Embeddable
public static class BinaryDataData implements Serializable {
@Column(length=32*1024*1024, columnDefinition="longblob", name="BINARY_DATA") @Lob
private byte[] actualData;
public BinaryDataData() { }
public BinaryDataData(byte[] data) {
this.actualData = data;
}
public byte[] getActualData() {
if (this.actualData == null) {
return new byte[0];
}
return this.actualData;
}
public void setBinaryData(byte[] newData) {
this.actualData = newData;
}
@Override public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof BinaryDataData)) {
return false;
}
final BinaryDataData other = (BinaryDataData) obj;
if (!Arrays.equals(actualData, other.actualData)) {
return false;
}
return true;
}
}
/** onwards... */
Unfortunately this doesn't work. The SQL that I'm seeing still shows a complete fetch of the object even if the binary data isn't requested:
select ideaattach0_.BINARY_DATA_ID as BINARY1_9_, ideaattach0_1_.BINARY_DATA as BINARY2_9_, ideaattach0_1_.BINARY_DATA_NAME as BINARY3_9_, ideaattach0_.IDEA_BUCKET_ID as IDEA2_136_ from IDEA_ATTACHMENT ideaattach0_ inner join BINARY_DATA ideaattach0_1_ on ideaattach0_.BINARY_DATA_ID=ideaattach0_1_.BINARY_DATA_ID where ideaattach0_.BINARY_DATA_ID=?
Any ideas? Thank you.
From Hibernate, Chapter 19. Improving performance:
这篇关于懒惰使用Hibernate获取单列(类属性)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!