Hibernate选择查询优化

时间:2015-10-23 13:55:13

标签: 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");
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();

但是,用第二种方式,我不能注射&#34; options对象中的client,因此我必须在代码中处理clientoptions个对象,并在options列出与合同相对应的列表我正在与之合作。

有没有办法用第二次请求的值完成Hibernate对象(我的例子中的客户端)?

感谢您的帮助。

PS:问:如果不清楚,我是法国人:)

3 个答案:

答案 0 :(得分:0)

<rant> 我一般都讨厌hibernate,因为当你手动编写SQL时,如果你只运行少数几次,那么它似乎会运行数百个查询 <\rant>

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

的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

然后我将它们全部放入适当的Map<Long, List>地图中并在java中进行连接。

答案 1 :(得分:0)

首先:你有多少数据,结果是第一个查询不起作用? 如果您的结果有这么多行并且您想要优化此查询,请检查您从db获得的所有数据是否真的需要。也许你应该投射到更平坦的其他物体。

如果您不使用Java处理数据并仅将其传递给前端,请考虑对结果进行分页。

答案 2 :(得分:-2)

使用Hibernate的好处是ORM。您可以将类设置为实体。因此,您不再需要担心简单的查询。只需使用JPA执行该任务即可。实体可能看起来像这样:

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

依旧......