我有一个正在使用的旧桌子,看起来像这样:
+------------------+--------------+------+-----+---------+-------+ | 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 | | +------------------+--------------+------+-----+---------+-------+
这样做的主要问题是,即使我只需要使用BinaryDataJava类也可以加载BINARY_DATA列BINARY_DATA_NAME。我知道,构造此文件的最佳方法是从元数据中拆分数据(例如文件名),以便它们位于单独的表中。从那里开始,使数据延迟加载很简单。这就是应该首先完成的方式。
BinaryData
BINARY_DATA
BINARY_DATA_NAME
不幸的是,由于组织限制,我可能无法执行上述操作。作为一种解决方法,是否可以使用某些注释将列延迟加载,而不是将其拆分为单独的表?我已经修改了BinaryData该类,使其具有一个内部静态BinaryDataData类,@Embedded并且该属性是@Basic(fetch=FetchType.LAZY):
BinaryDataData
@Embedded
@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... */
不幸的是,这不起作用。即使没有请求二进制数据,我看到的SQL仍显示对象的完整读取:
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=?
有任何想法吗?谢谢。
摘自Hibernate,第19章。提高性能:
延迟属性获取:访问实例变量时,将获取属性或单值关联。 这种方法需要构建时字节码检测 ,很少需要。