简体   繁体   English

休眠选择查询优化

[英]Hibernate Select Queries Optimization

I'm searching for the best way to optimize Hibernate select queries. 我正在寻找优化Hibernate select查询的最佳方法。

Here is a basic example: 这是一个基本示例:

BDD model 1 Client -> n Contracts -> n Options BDD模型1客户-> n合约-> n选项

The simplest manner to request all data of the client "xxxx" is something like: 请求客户端“ 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();

Sometimes this is just not possible since there are two much data to return. 有时这是不可能的,因为要返回两个数据。

So, I split the request, somethink like: 因此,我拆分了请求,例如:

// 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();

But, with the second manner, I can't "inject" options in client object, so I have to deal with client and options objects in my code, and search in options list those which correspond to the contract I'm working with. 但是,通过第二种方式,我无法在client对象中“注入” options ,因此我必须在代码中处理clientoptions对象,并在options列表中搜索与我正在使用的合同相对应的options

Is there a way to complete Hibernate object (client in my example) with values requested in a second time ? 有没有办法用第二次请求的值来完成Hibernate对象(在我的例子中是客户端)?

Thanks for your help. 谢谢你的帮助。

PS: ask if it's not clear, I'm French guy :) PS:问不清楚,我是法国人:)

<rant> I generally hate hibernate because it's such a time waster and also seems to run hundreds of queries when you'd only run a handful if writing the SQL manually <\\rant> <rant>我一般恨冬眠,因为它是这样一个浪费时间,也似乎运行数百个查询的时候,如果你手工编写的SQL会只能运行少数<\\rant>

If forced to use hibernate, I'd probably use 3 queries similar to 如果被迫使用休眠模式,我可能会使用3个类似的查询

  • from Options as o join fetch o.contract as co join fetch co.client as cl where cl = :client
  • from Contracts as co join fetch co.client as cl where cl = :client
  • from Client where clientId = :clientId

Then I'd put them all into appropriate Map<Long, List> maps and do the joins in java. 然后,将它们全部放入适当的Map<Long, List>映射中,并在Java中进行联接。

First: how much data do You have in result that the first query doesn't work? 第一:您有多少数据导致第一个查询不起作用? If you the result has so many rows and You want to optimise this query check if all data You get from db You realy need. 如果结果有这么多行,并且您想优化此查询,请检查是否确实需要从db获取的所有数据。 Maybe You should make a projection to other object which is more flattened. 也许您应该对更平坦的其他对象进行投影。

If you not process the data in Java and only passing it to the front-end consider pageing the result. 如果您不使用Java处理数据,而仅将其传递给前端,请考虑分页结果。

The benefit in using Hibernate is ORM. 使用Hibernate的好处是ORM。 You could set up your classes as Entities. 您可以将课程设置为实体。 So you don't need to worry about simple queries anymore. 因此,您不再需要担心简单的查询。 Simply use JPA for that task. 只需使用JPA即可完成该任务。 The entities could look like that: 实体看起来像这样:

@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;
    }
}

and so on... 等等...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM