如何优化或更改Hibernate生成的SQL语句
如何优化或更改Hibernate生成的SQL语句
我有一个单向的一对多关系,父对象拥有级联操作。
我想知道在插入、更新或删除时,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中的某个地方在运行时过滤/改进/替换查询?
以下是Parent/Child类,但我认为它不会有所帮助:
@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 Listchildren; public Parent(Long id, int value, List 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() { } }
如何优化或修改Hibernate生成的SQL语句
有人建议可以尝试在MySQL中使用rewriteBatchStatements
设置。这是一个在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
是的,我知道这个设置,但这更像是一个hack而不是一个解决方法。缺点是它也禁用了服务器端预处理语句。而且它不能解决更新/删除的问题。
嗯,我明白了。如果您在这里得不到满意的答案,我建议您在Hibernate的Zulip聊天室发表问题。(参见此链接并向下滚动:hibernate.org/community)