Db.batchSave丢字段数据的问题,旧事重提!

@JFinal

搜了以前的反馈,提到的这个问题:

https://jfinal.com/feedback/1109

Db.batchSave(modelList, batchSize)

这个方法,会根据modelList里第一个元素的属性值,生成insert语句。但是如果第一个元素里有一个字段,没给这个字段设置值,后面所有的成员里就是该字段有值,也会丢失该字段的值。看了JFinal的源码和波总的建议,可以使用

Db.batch(insertSql, columns, modelList, batchsize)

这种方式,强制指定insert语句,和需要处理的字段名,经过测试,这种方式是可行的。

这么看来,这也原本无可厚非。

但是,我觉得既然提供了batchSave方法,是否能改进一下代码,根据list里的Model或则Record,去取对应表里的所有字段,然后拼接成像

Db.batch(insertSql, columns, modelList, batchsize)

这个函数里的insertSql和columns,内部还是调用

Db.batch(insertSql, columns, modelList, batchsize)

这个方法,是不是可以降低不少代码量并且提高易用性呢。

根据Model或则Record获取对应表里的所有字段,这个应该是可行的。

波总在上面那个历史反馈里给的建议是自己扩展一个DbPro对象,然后覆盖batchSave方法。然后配置DbPro工厂是自己的这个对象,虽然可行,但有强迫症的,总觉得这种方式不纯了。以后升级JFinal,也会带来不少隐患。

烦请波总能重新考虑一下,把这个地方改进一下!

评论区

JFinal

2021-01-19 22:32

你的建议:"根据list里的Model或则Record,去取对应表里的所有字段,然后拼接成像"

这个应该是不好解决,我举个例子,假定有个表是 table_x, 字段有三个 (id, x, y)
1:假定字段 id、x 不能为 null ,也就是说 insert 语句必须要给定值
2:假定字段 y 可以为 null,你可以指定值也可以不指定
3:有时候 y 字段的值你是知道的,所以你可以指定,但有时候你不知道该指定为什么值

以上情况下,如果 jfinal 自做主张,生成的 sql 包含字段 y, 那么有些不指定 y 值的 Record/Model 该放入什么值?


其实你的需求,使用 Db.batch(...) 手动指定 sql 也是可以的,方法原型如下:
public int[] batch(String sql, String columns, List modelOrRecordList, int batchSize)

zzutligang

2021-01-20 13:54

@JFinal 生成的sql语句只是insert into table_x(id, x, y) values(?,?,?),然后后面具体跟什么数据,是根据list里的Model里的值决定的,如果list里某一个model里y没给值,那就放个null,给值了,就是用给的值。如果某个model里没给x值,但x字段又是必填的,那肯定是报错的,这就是写代码的人的问题了。其实我的想法就是在batchSave里自动拼接public int[] batch(String sql, String columns, List modelOrRecordList, int batchSize)这个函数的sql和columns这两个参数,然后调batch这个方法。不用每次都自己手动去写batch这个函数的前两个参数。

JFinal

2021-01-21 00:57

如果list里某一个model里y没给值,那就放个null,这个肯定不行

因为数据表字段是可以有默认值的,例如 jfinal.com 大量的默认值为 0 或者 1 的情况

不指定值与指定 null 值是完全不同的概念

zzutligang

2021-01-21 01:44

@JFinal,你说的有道理。因为我几乎很少依赖数据库的默认值,我一般设计库表结构的时候,如果有默认值,我会在数据字典里明确表明该字段有默认值,会要求程序员在写代码的时候,必须给该字段一个值,显示写到代码里,这样后期在换人接代码的时候,会比较容易理解,这只是个人习惯问题,所以就忽略你说的这种情况了。那么我这里的情况应该不是普遍情况,只是特例,所以,我这里就需要batchSave的时候,自己拼接sql语句和columns,然后调用batch方法了。就这么决定了。感谢波总的回复。不过,这个batchSave方法坑太大,估计不少人可能都会踩坑。按波总说的情况,如果batchSave方法里list参数的第一个元素的model字段是完整的,也就是设置了所有字段的值,但如果第二个model元素却有一个字段没设置值,并且这个字段也是有默认值的,那第二个元素保存到数据库里后该字段是不是也会被填充成null呢。
疑问是疑问,不过还是决定使用batch方法了。感谢波总会的关注和回复!