最近使用j8ql做ORM搭建了一套内部的Web Service/Web UI.
j8ql是比较小众的一个ORM类库, 主打轻量.
为什么不用Hibernate, MyBatis? 以前用过这两者, MyBatis是使用xml做Mapper, 实在不喜欢,配置也过于复杂, 造成本来就很小的Web Service应用太重.
这套内部的Web Service有批量插入的需求, 大概是数万条记录的批量插入.
为了提高性能, 采取batch insert的方式.
由于batch insert后, 需要更新另外一张关系表, 故需要取得batch insert生成的键值.
j8ql对java.sql的PreparedStatement和Statement类做了封装, 将部分Statement的接口作为API提供给应用使用.
j8ql的executeBatch接口封装了Statement的executeBatch接口, 返回的是int[], 代表insert的结果成功还是失败.
如果需要取得batch insert的键值, j8ql没有提供方式.
遍寻无解的时候, 发现java.sql的Statement接口有一个getGeneratedKeys的方法, 用于获取该Statement运行时auto-generated keys, 正是我所需要的方法.
问题是j8ql的Runner接口和RunnerImpl类并未暴露这个getGeneratedKeys.
只能自己搞了, 于是对j8ql做了如下改动:
- 为RunnerImpl新增了一个List
成员, 用于保存PreparedStatement/Statement对象执行完executeBatch后调用getGeneratedKeys获取的结果; - 为Runner新增了一个getGeneratedKeys方法, 返回这个List
成员.
代码改完, 测试过程中, 发现在PreparedStatement/Statement在executeBatch后调用PreparedStatement/Statement的getGeneratedKeys依然取不到生成的键值.
Google后发现, Statement在prepateStatement时, 需要设置第二个参数autoGeneratedKeys为1, 方能使getGeneratedKeys返回结果.
UT完成后, 大功告成.
生成pull request提交给j8ql的owner做review和merge:
https://github.com/BriteSnow/j8ql/pull/12