Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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_Hibernate_Select_Hql - Fatal编程技术网

Java Hibernate选择查询优化

Java Hibernate选择查询优化,java,hibernate,select,hql,Java,Hibernate,Select,Hql,我正在寻找优化Hibernate select查询的最佳方法 以下是一个基本示例: BDD模型 1个客户->n个合同->n个选项 请求客户端xxxx的所有数据的最简单方式如下: final Query hqlQuery = jdbcTemplate.createHQLQuery("from Client cli left join fetch cli.contracts con left join fetch con.options where cli.id=:idClient"); hqlQu

我正在寻找优化Hibernate select查询的最佳方法

以下是一个基本示例:

BDD模型 1个客户->n个合同->n个选项

请求客户端xxxx的所有数据的最简单方式如下:

final Query hqlQuery = jdbcTemplate.createHQLQuery("from Client cli left join fetch cli.contracts con left join fetch con.options where cli.id=:idClient");
hqlQuery .setString("idClient", "xxxx");

Client client = (Client) hqlQuery.uniqueResult();
有时这是不可能的,因为有两个数据要返回

所以,我把请求分成两部分,比如:

// Query 1
final Query hqlQueryClient = jdbcTemplate.createHQLQuery("from Client cli left join fetch cli.contracts where cli.id=:clientId");
hqlQueryClient.setString("clientId", "xxxx");

Client client = (Client) hqlQueryClient.uniqueResult();

List<String> listContractIds = new ArrayList<String>();

for (Contract contract : client.getContracts()) {
  listContractIds.add(contract.getId());
}

// Query 2
final Query hqlQueryOptions = jdbcTemplate.createHQLQuery("from Option opt where opt.contract.id in(:contractIds)");
hqlQueryOptions.setParameterList("contractIds", listContractIds);

List<Option> options = hqlQueryClient.list();
但是,使用第二种方式,我不能在客户机对象中注入选项,因此我必须在代码中处理客户机和选项对象,并在选项列表中搜索与我正在处理的合同对应的选项

在我的示例中,有没有一种方法可以使用第二次请求的值来完成Hibernate对象客户端

谢谢你的帮助

附言:如果不清楚,问一下,我是法国人:

我通常讨厌hibernate,因为它非常浪费时间,而且在手动编写SQL时只运行少量查询的情况下,它似乎也会运行数百个查询

如果被迫使用hibernate,我可能会使用3个类似于

从选项中选择o join fetch o.CONTACT as co join fetch co.client as cl,其中cl=:client 从作为共同加入的合同中获取作为cl的共同客户,其中cl=:client 来自clientId=:clientId的客户端
然后我将它们都放入适当的映射中,并在java中进行连接。

使用Hibernate的好处是ORM。您可以将类设置为实体。因此,您不再需要担心简单的查询。只需将其用于该任务。实体可以是这样的:

@Entity
public class Client implements Serializable {
    private Long id;
    private ArrayList<Contract> contracts;
    // more attributes here
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    @OneToMany
    public ArrayList<Contract> getContracts() {
        return contracts;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setContracts(ArrayList<Contract> contracts) {
        this.contracts = contracts;
    }
}

@Entity
public class Contract implements Serializable {
    private Long id;
    private List<Option> options;
    // more attributes here
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long getId() {
        return id;
    }

    @OneToMany
    public List<Option> getOptions() {
        return options;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setOptions(List<Option> options) {
        this.options = options;
    }
}

依此类推……

首先:您有多少数据导致第一个查询不起作用? 如果您想要优化这个查询,那么请检查您从db获得的所有数据是否都是您真正需要的。也许你应该投影到另一个更平坦的物体上


如果你不处理java中的数据,只将它传递到前端,考虑结果的pAGE.

HI,你的回答是不符合上下文的,我的问题不是关于映射,而是如何从POV中高效地查询,你想用Hibernate强制编写SqLQS。这完全脱离了上下文,因为您甚至不了解Hibernate的用途。因此,你没有办法直接将3个查询的结果注入到主对象中,而不是处理Map?如果你只从Option->Contract->Client导航,第一个查询可能就可以了。如果你走另一条路——客户->合同->选项,你会遇到问题。你是对的,但在我的代码中,我无法从选项->合同->客户导航,我正在做另一条路——客户->合同->选项。为了避免n+1选择问题,我从不调用contrat.getOptions。相反,我通过contrat id以编程方式过滤选项查询的结果,但它不像调用contart.getOptions那样干净,这是本文的主题:如何做得更好:我回答了文章的主题:3查询+映射:不完全是。问题是:是否可以请求您提出的方法,然后将结果注入示例中的顶级对象客户机,以便能够直观地迭代客户机子级?所以我估计你的回答是否定的,这是不可能的:潜在的1个客户->50个合同->50个选项让我们假设每个客户,每个合同和每个选项有20列,这意味着Hibernate必须处理50*20*50*20=1000000列。你真的需要所有这些列吗?不是全部,但至少是50%。所以首先,你应该只选择你需要的列。第二个问题是如何处理数据?您是否用Java处理数据?关于列,您是对的,但是如何从客户机、合同、选项三个级别的对象中选择我想要的列,并将结果映射到我的客户机对象上?关于处理,是的,我用Java处理这些结果。