Hibernate按子属性排序实体,映射为Map <string,child =“”>

时间:2016-03-16 11:47:26

标签: java hibernate

这是我的模特:

$query = $pdo->query("select * from tab1 order by date_time ASC");
$calls = array();
foreach($query as $row){
    //check the differences
    $from = substr($row['from'],4,15); //remove prefix
    $date_time = date('Y-m-d H:i:s'
               , strtotime('-2 minute',strtotime($row['date_time']))); 
               //decrese of 2 min the time to match all time differences
    $duration = $pdo->query(
       "select duration
        , abs(duration - ".$row['duration'].") as duration_diff
        , price from tab2 
        where date_time between '".$date_time."' and '".$row['date_time']."' 
        and from like '%".$row['from']."' 
        and duration >0 
        order by duration_diff"
      )->fetch();

    //highlight the differences
    if ($row['duration'] > $duration['duration'] ):
        $color = "#ff0000";
    elseif ($row['duration'] < $duration['duration'] ):
        $color = "#ff9900";
    else:
        $color = "#fff";
    endif;
    $calls[] = array(
       "date_time" => $row['date_time'], 
       "from" => $row['from'], 
       "to" => $row['to'], 
       "duration_tab1" => $row['duration'], 
       "duration_tab2" => $duration['duration'], 
       "price_tab1" => $row['price'], 
       "price_tab2" => substr($duration['price'],0,6), 
       "color" => $color);
  }

该映射非常有用,可用于插入,更新,删除entites和选择它们。

现在我必须根据map键来命令Parent entites使用他们的子属性,类似于@Entity @Table(name = "parent") public class Parent { ... @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REMOVE}, mappedBy = "parent") @MapKeyColumn(name = "key") private Map<String, Child> children; ... } @Entity @Table(name = "child") public class Child { ... @Column(name = "key") private String key; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") private Parent parent; @Column(name = "property") private String property; ... } 子句(我在HQL中找不到)。我也不知道如何使用Criteria API实现这一目标。有什么想法吗?

我现在只有解决方案是选择按order by parent.children[<particular key>].property asc过滤并按key排序的子项,然后逐个获取Java代码中的父项,即使使用&#34; fetch parent&#也无效34;组。

1 个答案:

答案 0 :(得分:1)

表创建的语句如下:

create table child (id bigint not null, key varchar(255), property varchar(255), parent_id bigint, primary key (id))
create table parent (id bigint not null, primary key (id))

对父表的parent_id有约束。

向后工作,sql似乎很直接:

select p.* from parent p join child c on p.id = c.parent_id where c.key = 'c1' order by c.property asc;

所以JPQL和Criteria查询也应该是直截了当的:

List<Parent> po1 = em.createQuery("select p from Parent p join p.children c where c.key='c1' order by c.property asc", Parent.class).getResultList();
System.out.println(po1);

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Parent> cq = cb.createQuery(Parent.class);
Root<Parent> p = cq.from(Parent.class);
Join<Parent, Child> c = p.join("children");
cq.select(p).where(cb.equal(c.get("key"), "c1")).orderBy(cb.asc(c.get("property")));
List<Parent> po3 = em.createQuery(cq).getResultList();
System.out.println(po3);

为Parent创建一个toString方法:

public String toString() {
    return "Parent:"+id+":"+children;
}

和孩子:

public String toString() {
    return "Child:"+id+":"+key+":"+property;
}

这给了我以下输出:

Hibernate: select parent0_.id as id1_1_ from parent parent0_ inner join child children1_ on parent0_.id=children1_.parent_id where children1_.key='c1' order by children1_.property asc
[Parent:4:{c1=Child:5:c1:0}, Parent:1:{c1=Child:2:c1:1}]
Hibernate: select parent0_.id as id1_1_ from parent parent0_ inner join child children1_ on parent0_.id=children1_.parent_id where children1_.key=? order by children1_.property asc
[Parent:4:{c1=Child:5:c1:0}, Parent:1:{c1=Child:2:c1:1}]

我认为这是由子属性订购的父母,其中密钥是特定值。