jfinal使用model更新数据时的缺陷

场景:用户绑定微信,一个用户只能绑定一个微信,一个微信也只能绑定一个用户。

表t_sys_user_wechat有2个字段,user_code(唯一索引),openid(主键)


过程:

第一次user1绑定了openid1,成功后

第二次openid2绑定user1,想要的效果是openid1被替换

伪代码:

Model model = getByUserId(user1);

model.setOpenId(openid2);

model.update()

想要的结果为:update t_sys_user_wechat set openid = openid2 where openid = openid1;

实际的结果为:update t_sys_user_wechat set openid = openid2 where openid = openid2;

where条件本想要openid1,结果变成了openid2。

而且,想当然的不使用openid来绑定user_code而使用user_code绑openid,用user_code当主键,openid当唯一索引,一样会有这个问题。

最后解决方案:

Model model 1= getByUserCode(user1);

model1.deleteOnExists();


Model model2 = getByUserCode(openid1);

model2.deleteOnExists();


Model model3 = new Model(user_code,openid);

model3.save();

删除所有存在的绑定关系,重新建立绑定。



建议:jfinal能否支持,通过select出来的model,在update的时候,使用原始主键作为where条件

格式大概为:

model.update(true);  参数表示是否使用原始值作为主键更新,默认为(false),即update()表示不使用跟现有效果保持一致。


评论区

jounzhang

2020-07-11 15:46

杜福忠

2020-07-11 16:21

或许表结构改一下更合适
表t_sys_user_wechat有3个字段,ID,user_code(唯一索引),openid(唯一索引)

JFinal

2020-07-11 16:46

这个需求太偏应用了,好好修改主字段值就好

zzutligang

2020-07-13 10:12

@JFinal 其实,就是想实现update mytable set pk=newpkvalue where pk=oldpkvalue,这个需求还是蛮多的

jounzhang

2020-07-17 12:05

@杜福忠 @JFinal 这位大哥@zzutligang 说的对,这个与应用无关,就是想实现
update mytable set pk=newpkvalue where pk=oldpkvalue,问题的根本原因就是复合主键的问题,但是不可避免复合主键还是在很多地方存在。而且复核主键可以避免单独创建索引,以后的设计中确实会尽量避免复合主键。因为jfinal本身是支持复合主键的,所以如果能支持这种用法的话,就更爽了

JFinal

2020-07-17 12:31

@jounzhang 改主键值通常是错误的,因为别的 table 很可能早有很多数据与该主键进行了关联,从而会造成数据一致性问题。除非是很特殊的情况,一般不建议这么用

此外,改主键当然最好是用 Db.update(....) 来操作,无论是单主键还是多主键都十分方便。并且 Db.update(...) 还可以批量改主键,而 Model 要做到改主键的功能,只能一次改一个 model

zzutligang

2020-07-18 14:05

@JFinal 我现在涉及到更新主键字段的操作(主要是复合主键),就是用Db对象操作。如果按你说的,Model能做到改主键的功能,就算一次只能改一个,也有必要!希望下一个版本能提供model的这个功能。

热门反馈

扫码入社