在HIBERNATE中进行了一对多的映射,从一查出多,想把多的放在列表中,产生的数据是想同的,遍历后显示在界面上,相同的数据顺序就不一样了,很影响数据查看,如下面效果:

排序前:

8694a4c27d1ed21b4fa18b0faf6eddc450da3feb

排序后(问题解决):

ac6eddc451da81cb7e8e26275066d016082431eb

修改HIBERNATE的配置文件(红色部分,project_t为project表的字段):

<set name="projects" cascade="all" lazy="false" order-by="project_t desc">

    <key>

        <column name="user_t" />

    </key>

    <one-to-many class="com.haier.db.entity.User_project_t" />

</set>


Collection结果集排序解析


  无序集和有序集,是针对Hibernate数据持久过程中,是否保持数据集合中的记录排列顺序加以区分的。

  也就是说,对于一个有序集,其中元素的排列次序将会在库表中制定的字段中保存,而下次读取时,也会以同样的次序排列。下面所要探讨的,则是关于Collection中的元素排序问题。

  排序强调的是针对现有数据,以特定的逻辑对其排列次序进行调整。而排序的结果,是数据在内存中的某种排列次序,属于临时状态。

  数据排序由两种方式:

  1.    Sort

  Collection中的数据排序。如对一个List中的元素先后顺序进行调整。

  2.    order-by

  对数据库执行Select SQL时,由order by子句实现的数据排序方式。

可以看出,这两种排序方式的最基本差异在于,Sort操作是在JVM中完成,而order-by是由数据库完成。


1. Sort

首先来看一个示例:

  <set  name=”addresses” lazy=”true” table=”t_address” sort=”naural”>

    <key  column=”user_id”/>

    <element  type=”string”  column=”address”/>

  </set>

  可排序Set在Hibernate中对应的实现类为net.sf.hibernate.collection.SortedSet,它实现了java.util.SortedSet接口。

sort=”natural”指定采用Java默认排序机制,它会调用相应数据类型的compareTo方法进行排序中的值比对。这里<element type=”string”…>指定了元素类型为string,也就是说,排序将基于String.compareTo方法。

  如果期望指定某种特殊的排序算法,那么我们可以实现java.util.Comparator接口,并以此实现作为排序的根据。如下面这段代码:

  /**

  *基于字符串长度的比对

  */

  public class LengthComparator implements Comparator{

    public int compare(Object obj1, Object obj2){

      String str1 = String.valueOf(obj1);

      String str2 = String.valueOf(obj2);

      return str1.length()-str2.length();

    }

  }

  作为示例,LengthComparator实现了字符串长度的比对,我们可以在配置中指定LengthComparator作为排序算法:

  <set  name=”addresses” lazy=”true” table=”t_address” sort=”org.sample.LengthComparator”>

    <key column=”user_id”/>

    <element type=”string” column=”address”/>

  </set>

  Map类型的排序与Set基本一致:

  <map  name="addresses" lazy="true" table="t_address" sort="org.sample.LengthComparator">

    <key column="user_id"/>

    <element type="string" column="address"/>

        </map>

  index呢,可排序Map在Hibernate中对应的实现类为net.sf.hibernate.collection.SortedMap,它实现了java.util.SortedMap接口。net.sf.hibernate.collection.SortedMap和.SortedSet的内部实现分别基于java.util.TreeSet和java.util.TreeMap。而Bag和List由于实现原理的不同(且JDK中也并不存在所谓的TreeList),并不支持sort排序方式。


2. order-by

  Collection的order-by排序方式,其实现原理也是借助SQL的order by子句。

  同样来看一个示例:

     <set  name="addresses" lazy="true" table="t_address" order-by="address desc">

          <key column="user_id"/>

          <element type="string" column="address"/>

     </set>

  在order-by属性中,我们指定了SQL排序子句。Hibernate在自动生成SQL时,会根据此项配置,自动在SQL中追加相应的order by子句。

  运行以下代码:

  TUser user = (TUser)session.load(TUser.class, new Integer(1));

  Iterator it = user.getAddresses().iterator();

  while(it.hasNext()){

    String addr = (String)it.next();

    System.out.println(addr);

  }

  观察Hibernate生成的SQL语句:

可以看到,Hibernate在生成SQL的时候,已经追加了order-by子句“order by addresses0_.address asc”.

  注意:

  order-by特性在实现中借助了JDK1.4中的新增集合类LinkedHashSet以及LinkedHashMap,因此order-by特性只支持在1.4版本以上的JDK中运行。

  Set、Map、Bag均支持order-by排序,有序集List例外。