从连接表中获取一个只读字段的最佳方法?

时间:2010-07-28 15:26:28

标签: hibernate

很多时候,我们只需要一个连接表中的一个只读字段。例如,在以下情况下,我只需要来自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> 

1 个答案:

答案 0 :(得分:0)

如果您想避免阅读太多列,那么您实际上并没有很多解决方案:

  1. 使用SQL投影(对于类型安全结果可能是select new),
  2. 如您所述,使用较轻的物品,
  3. 使用lazy property fetching。
  4. 关于最新的选项,我建议仔细阅读文档的相关部分:

      

    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。