java - 如何优化或更改 hibernate 生成的 SQL 语句

标签 java hibernate jpa

我有一个与级联拥有的非定向 OneToMany 关系父级。

我想知道是否有一种方法可以优化 ORM 在插入、更新或删除时所做的请求。我知道如何配置批处理,但我看到了其他改进方式,ORM 正在执行的许多请求可以在单个查询中完成。

例如,考虑以下操作 entityManager.persist(parent) :

0 ms|statement|insert into parent (value) values (1)
0 ms|statement|insert into child (value) values (1)
0 ms|statement|insert into child (value) values (1)
3 ms|statement|insert into child (value) values (1)
0 ms|statement|update child set parent_id=1 where id=1
0 ms|statement|update child set parent_id=1 where id=2
0 ms|statement|update child set parent_id=1 where id=3

可以替换为(至少对于 mysql 方言):
insert into parent (value) values (1);
insert into child (value) values (1),(1),(1);
update child set parent_id=1 where id in (1, 2, 3);

级联删除也有同样的问题并且是可优化的。

hibernate 怎么可能检测不到这样的优化?我们是否有办法在 ORM 中的某处 Hook 以在运行时过滤/改进/替换查询?

这是父/子类,但我认为它不会有帮助:
@Entity
public class Parent {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    public int value;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "parentId", referencedColumnName = "id")
    public List<Child> children;

    public Parent(Long id, int value, List<Child> children) {
        this.id = id;
        this.value = value;
        this.children = children;
    }

    private Parent() {
    }
}

@Entity
public class Child {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;

    int value;

    public Child(Long id, int value) {
        this.id = id;
        this.value = value;
    }

    private Child() {
    }
}

最佳答案

也许你可以试试 rewriteBatchStatements设置mysql?这是您添加到 JDBC 连接 URL 的设置,它重写大量插入语句并将它们内联到单个语句中,从而提高运行时间。我认为您还需要启用您已经为此所做的批处理。

见:MySQL and JDBC with rewriteBatchedStatements=true

以及此链接中的 mysql rewriteBatchedStatements 配置属性(您必须按 CTRL+F 才能找到它):https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html

关于java - 如何优化或更改 hibernate 生成的 SQL 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59457206/

相关文章:

java - 运行服务器瓶颈测试

java - 为什么这个函数不打印所有的值?

java - 文件读取器直到最后才读取所有数据

java - 序列化斯坦福解析器对象

hibernate - 具有该名称 [userName] 的参数不存在

java - 实体对象作为 HQL 参数

java - 字符串映射不能处理超过 varchar(255)

java - Hibernate删除行和外键行ManyToOne

java - Hibernate 映射通过引用未知目标实体

java - JPA 与 Google Cloud SQL "NoClassDefFoundError: java.util.prefs.Preferences is a restricted class"