itfsw / mybatis-generator-plugin

Mybatis Generator 代码生成插件拓展,增加:查询单条数据插件(SelectOneByExamplePlugin)、MySQL分页插件(LimitPlugin)、数据Model链式构建插件(ModelBuilderPlugin)、Example Criteria 增强插件(ExampleEnhancedPlugin)、Example 目标包修改插件(ExampleTargetPlugin)、批量插入插件(BatchInsertPlugin)、逻辑删除插件(LogicalDeletePlugin)、数据Model属性对应Column获取插件(ModelColumnPlugin)、存在即更新(UpsertPlugin)、Selective选择插入更新增强插件(SelectiveEnhancedPlugin)、Table增加前缀插件(TableSuffixPlugin)、自定义注释插件(CommentPlugin)、增量插件(IncrementsPlugin)、查询结果选择性返回插件(SelectSelectivePlugin)、乐观锁插件(OptimisticLockerPlugin)、LombokPlugin等拓展。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

可否为batch_insert增加 insert if not exists 逻辑?

id4alex opened this issue · comments

因为很多时候有 insert if not exists 批量插入的需求, 是一个很实用功能.

本来这个repo[https://github.com/beihaifeiwu/dolphin] 已经完成了这个功能,但是觉得他的其他功能写的没你的好, 所以恳请您的repo里面添加这项功能.

你好,我Github邮箱好像出问题了,一直没有收到这个issue,我看了下https://github.com/beihaifeiwu/dolphin上最新的代码逻辑,其实他已经没有再采用insert if not exists 这种逻辑,因为这要求数据库链接配置需开启allowmultiqueries=true批量执行sql,而且代码逻辑上其实是先执行了一个带条件update然后是带条件插入,这个效率不是很高。
所以我还是考虑按最新的实现上使用mysql “on duplicate key update” 语法来增加这种存在即更新的逻辑,当然如果需要继续采用类似upsertByExample这种和MongoDB类似逻辑,我也会添加支持,但默认不开启,需要的话在插件property配置中增加<property name="allowMultiQueries" value="true"/>来开启支持,但不建议使用。

新版本已出,考虑下你提的需求,可能并不是真的需要类似MongoDB类似upsertByExample这种情况。大多数情况下应该还是根据主键来进行存在即更新操作,所以UpsertPlugin依然只采用MySQL的on duplicate key update 进行实现。
至于upsertByExample实现延后有好的方法时继续跟进。

感谢你的更新. 抱歉我没有说太清楚.

通常会有一些爬虫的功能,一次性获取几百条记录回来,有的记录通常总量在几千万条量级. 通常的逻辑都是每条记录在java中做查询存在就更新,不存在就插入 这样的操作(通常需要2* list.size() 的 jdbc操作数). 我就想着把这部分的功能往下移到mybatis里面通过一次jdbc操作,完成批量操作,效率会有所提升.

生成的批量sql应该下面这样的一个批量sql去一次执行.
update xxx where if not exists(select xxx where id=id1);
insert xxx where if not exists(select xxx where id=id1);
update xxx where if not exists(select xxx where id=id2);
insert xxx where if not exists(select xxx where id=id2);
update xxx where if not exists(select xxx where id=id3);
insert xxx where if not exists(select xxx where id=id3);

但是通常表结构设计longid 自增作为物理主键, xxxx_hashid(例如user_hashid)作为逻辑主键, 一般我会根据hashid去做判断这条记录存在与否,而不是自增ID(longid) .在这样的情况下我们可能就需要多传递一个field_name(xxxx_hashid) 作为 参数进来.

update xxx where if not exists(select xxx where xxx_hashid=id1);
insert xxx where if not exists(select xxx where xxx_hashid=id1);
update xxx where if not exists(select xxx where xxx_hashid=id2);
insert xxx where if not exists(select xxx where xxx_hashid=id2);
update xxx where if not exists(select xxx where xxx_hashid=id3);
insert xxx where if not exists(select xxx where xxx_hashid=id3);

以上是我的一些想法, 不知道我有没有表述清楚, 先提前谢了!

新快照版本已出,增加插件属性设置为<property name="allowMultiQueries" value="true"/>情况下支持upsertByExample,upsertByExampleSelective操作,但强力建议不要使用(需保证团队没有使用statement提交sql,否则会存在sql注入风险)。