Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate联合备选方案_Java_Sql_Hibernate_Union - Fatal编程技术网

Java Hibernate联合备选方案

Java Hibernate联合备选方案,java,sql,hibernate,union,Java,Sql,Hibernate,Union,使用hibernate实现联合查询需要哪些替代方案?我知道hibernate目前不支持联合查询,现在我看到的唯一实现联合的方法是使用视图表 另一种选择是使用普通jdbc,但这样我就失去了所有示例/标准查询,以及hibernate对表/列执行的hibernate映射验证。使用视图。可以使用实体名称将相同的类映射到不同的表/视图,因此您甚至不会有太多的重复。在那里,那样做,效果很好 普通JDBC还有另一个隐藏的问题:它不知道Hibernate会话缓存,因此,如果某个东西缓存到事务结束,并且没有从Hi

使用hibernate实现联合查询需要哪些替代方案?我知道hibernate目前不支持联合查询,现在我看到的唯一实现联合的方法是使用视图表


另一种选择是使用普通jdbc,但这样我就失去了所有示例/标准查询,以及hibernate对表/列执行的hibernate映射验证。

使用视图。可以使用实体名称将相同的类映射到不同的表/视图,因此您甚至不会有太多的重复。在那里,那样做,效果很好


普通JDBC还有另一个隐藏的问题:它不知道Hibernate会话缓存,因此,如果某个东西缓存到事务结束,并且没有从Hibernate会话中刷新,JDBC查询将找不到它。有时候可能会很困惑。

我不得不同意弗拉基米尔的观点。我也研究过在HQL中使用UNION,但找不到解决方法。奇怪的是,我可以在Hibernate FAQ中发现UNION是不受支持的,关于UNION标记为“fixed”的错误报告,人们的新闻组说这些语句将在UNION被截断,其他人的新闻组报告它工作正常。。。
经过一天的努力,我最终将我的HQL移植回了普通SQL,但在数据库的视图中这样做将是一个不错的选择。在我的例子中,部分查询是动态生成的,因此我必须在代码中构建SQL。

视图是更好的方法,但由于hql通常返回列表或集合。。。您可以执行list_1.addAlllist_2。与工会相比,这太糟糕了,但应该可以工作。

我也经历过这种痛苦-如果查询是动态生成的,例如Hibernate条件,那么我就找不到一种切实可行的方法

对我来说,好消息是,在Oracle数据库中使用“or”时,我只是为了解决性能问题而调查union


Patrick发布的解决方案使用一个集合以编程方式组合结果,虽然很难看,但特别是因为我也想进行结果分页,这对我来说已经足够了。

也许我有一个更直接的问题要解决。我的“例如”是在JPA中,Hibernate是JPA的提供者

在第二种情况下,我将三个select和两个select拆分为多个select,并将自己返回的集合组合在一起,有效地取代了“union all”

您可以在从中选择id时使用id。。。或从中选择id中的id

e、 g.而不是不工作

你可以

from Person p 
  where p.id in (select p1.id from Person p1 where p1.name="Joe") 
    or p.id in (select p2.id from Person p2 join p2.children c where c.name="Joe");
不过,至少在使用MySQL时,您以后会遇到性能问题。有时,在两个查询上进行穷人连接更容易:

// use set for uniqueness
Set<Person> people = new HashSet<Person>((List<Person>) query1.list());
people.addAll((List<Person>) query2.list());
return new ArrayList<Person>(people);

最重要的是,1。行不使用任何索引,并考虑200k+行。令人不快的此查询的执行时间为0.7秒,其中两个子查询均以毫秒为单位

我有一个关键场景的解决方案,我在HQL中与union进行了大量的斗争

e、 g.与其不工作,不如:-

您可以在Hibernate HQL中执行->

然后您可以添加这两个列表->

l1.addAll(l2);
正如Patrick所说,在每个SELECT中添加列表将是一个好主意,但请记住,它的行为类似于UNION ALL。为了避免这种副作用,只需控制对象是否已添加到最终集合中。如果没有,则添加它。 您还需要注意的是,如果在每个SELECT中有任何连接,则结果将是一个object arrayList列表,因此您必须对其进行迭代,以仅保留所需的对象。
希望它能起作用。

这里有一个特例,但它可能会激励您创建自己的工作环境。这里的目标是统计两个不同表中记录满足特定条件的记录总数。我相信这种技术适用于需要跨多个表/源聚合数据的任何情况

我设置了一些特殊的中间类,因此调用命名查询的代码简短而甜美,但是您可以使用通常与命名查询结合使用的任何方法来执行查询

QueryParms parms=new QueryParms();
parms.put("PROCDATE",PROCDATE);

Long pixelAll = ((SourceCount)Fetch.row("PIXEL_ALL",parms,logger)).getCOUNT();
正如您在这里所看到的,命名查询开始看起来非常像union语句:

@Entity
@NamedQueries({
        @NamedQuery(
            name  ="PIXEL_ALL",
            query = "" +
                    "  SELECT new SourceCount(" +
                    "     (select count(a) from PIXEL_LOG_CURR1 a " +
                    "       where to_char(a.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
                    "     )," +
                    "     (select count(b) from PIXEL_LOG_CURR2 b" +
                    "       where to_char(b.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
                    "     )" +
                    ") from Dual1" +
                    ""
    )
})

public class SourceCount {
    @Id
    private Long   COUNT;

    public SourceCount(Long COUNT1, Long COUNT2) {
        this.COUNT = COUNT1+COUNT2;
    }

    public Long getCOUNT() {
        return COUNT;
    }

    public void setCOUNT(Long COUNT) {
        this.COUNT = COUNT;
    }
}
这里的神奇之处在于创建一个虚拟表并在其中插入一条记录。在我的例子中,我将其命名为dual1,因为我的数据库是Oracle,但我认为它与您所称的虚拟表无关

@Entity
@Table(name="DUAL1")
public class Dual1 {
    @Id
    Long ID;
}
不要忘记插入虚拟记录:

SQL> insert into dual1 values (1);

更令人费解的是,当您有了二级缓存,但使用普通的JDBC从应用程序的其他部分进行报告时。解决方案之一是使用聚合实体,如前所述。感谢您列举了您发现的各种理论,以及哪些理论是不正确的。一个合理的开发人员可能期望的东西和与之不同的东西之间的差异是一些最有用的注释。联合将是过程中的,而不是由数据库完成的,这与Walt的建议是一样的
你想在这里分类吗?您可能会通过实现另一个合并算法来复制排序机制。非常不好如果你想分页,你不能使用两个子查询,不是吗?+1来自我。虽然,两个简单的查询通常比一个复杂的查询好,但是一个使用适当索引的查询通常更好。那么返回不同类型的查询呢?因此,一个类型A的列表和第二个类型B的列表具有相同的属性,如表A用于实时数据,表B用于历史数据
l1.addAll(l2);
QueryParms parms=new QueryParms();
parms.put("PROCDATE",PROCDATE);

Long pixelAll = ((SourceCount)Fetch.row("PIXEL_ALL",parms,logger)).getCOUNT();
@Entity
@NamedQueries({
        @NamedQuery(
            name  ="PIXEL_ALL",
            query = "" +
                    "  SELECT new SourceCount(" +
                    "     (select count(a) from PIXEL_LOG_CURR1 a " +
                    "       where to_char(a.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
                    "     )," +
                    "     (select count(b) from PIXEL_LOG_CURR2 b" +
                    "       where to_char(b.TIMESTAMP, 'YYYYMMDD') = :PROCDATE " +
                    "     )" +
                    ") from Dual1" +
                    ""
    )
})

public class SourceCount {
    @Id
    private Long   COUNT;

    public SourceCount(Long COUNT1, Long COUNT2) {
        this.COUNT = COUNT1+COUNT2;
    }

    public Long getCOUNT() {
        return COUNT;
    }

    public void setCOUNT(Long COUNT) {
        this.COUNT = COUNT;
    }
}
@Entity
@Table(name="DUAL1")
public class Dual1 {
    @Id
    Long ID;
}
SQL> insert into dual1 values (1);