很多时候,我们只需要一个连接表中的一个只读字段。例如,在以下情况下,我只需要来自Customers表的(客户)名称。为此,我创建了整个Customer对象,该对象由Orders中不需要的数十个其他属性组成。
如果为子类获取此类字段(例如,项目对象的(产品)名称),则此问题变得更加重要。这导致为一个订单创建数百甚至数千个“产品”对象,只是为了提供产品名称
处理这种情况的一种方法是使用一个属性创建一个额外的CustomerName类。这种方法看起来并不优雅,因为它最终可能会为同一个表创建许多类似的类。
有人可以建议我一个更好的解决方案吗?
使用常规客户和产品类进行映射的示例:
<class name="Order" table="Orders">
<id column="ID" name="id" type="long">
<generator class="native" />
</id>
<property name="customerId" type="int" />
<many-to-one class="Customer" name="customer" column="customerId" insert="false" update="false" fetch="join" />
<class name="OrderItem" table="OrderItems">
<id column="id" name="itemId" type="long">
<generator class="native" />
</id>
<property name="productId" type="long" />
<many-to-one name="order" column="orderId" not-null="true" />
<many-to-one class="Product" name="product" column="productId" insert="false" update="false" fetch="join" />
</class>
</class>
其他CustomerName和ProductName类的示例:
<class name="Order" table="Orders">
...
<many-to-one class="CustomerName" name="customer" column="customerId" insert="false" update="false" fetch="join" />
<class name="OrderItem" table="OrderItems">
.....
<many-to-one class="ProductName" name="product" column="productId" insert="false" update="false" fetch="join" />
</class>
</class>
答案 0 :(得分:0)
如果您想避免阅读太多列,那么您实际上并没有很多解决方案:
关于最新的选项,我建议仔细阅读文档的相关部分:
19.1.7. Using lazy property fetching
Hibernate3支持延迟抓取 个人财产。这个 优化技术也是已知的 作为获取组。请注意这一点 主要是营销功能; 优化行读取更多 比柱优化更重要 读取。但是,只加载一些 类的属性可能很有用 在极端的情况下。例如,何时 遗留表有数百列 并且数据模型无法改进。
要启用延迟属性加载,请设置 特定的懒惰属性 属性映射:
<class name="Document"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="50"/> <property name="summary" not-null="true" length="200" lazy="true"/> <property name="text" not-null="true" length="2000" lazy="true"/> </class>
懒惰的属性加载需要 构建时间字节码检测。如果 你的持久化课程不是 增强,Hibernate会忽略懒惰 属性设置并返回 立即抓取。
对于字节码检测,请使用 跟随Ant任务:
<target name="instrument" depends="compile"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask"> <classpath path="${jar.path}"/> <classpath path="${classes.dir}"/> <classpath refid="lib.class.path"/> </taskdef> <instrument verbose="true"> <fileset dir="${testclasses.dir}/org/hibernate/auction/model"> <include name="*.class"/> </fileset> </instrument> </target>
一种不同的避免方式 不必要的列读取,至少为 只读事务,就是使用了 HQL或Criteria的投影功能 查询。这避免了需要 构建时间字节码处理和 当然是首选的解决方案。
你可以强制通常的渴望获取 使用fetch all的属性 HQL中的属性。
就个人而言,我首先赞成选项#1。如果不可能的话,我会选择#2选项(是的,它会引入更多的维护,但是如果你只将这个解决方案用于真正有问题的部件,你可以控制它)。我不喜欢选项#3。