Comments (22)
我记得update方法就是如果没有的话就insert,有的话就update。
我现在不是很确定了,你可以测试一下
from ctpersistance.
我测试过了,是不会merge的。
看源码,CTPersistanceTable+Update 里的update方法最终会走到这样的SQL语句——[NSString stringWithFormat:@"UPDATE %@
SET %@ WHERE %@;", tableName, valueString, whereString];
应该是不会merge的了……
from ctpersistance.
嗯,我明天白天写,今天晚上回家我要打游戏。
from ctpersistance.
多谢多谢!😂
from ctpersistance.
- (void)upsertRecord:(NSObject <CTPersistanceRecordProtocol> *)record
uniqKeyName:(NSString *)key
error:(NSError **)error
这样的API接口适合你的场景么?
from ctpersistance.
简直完美!
from ctpersistance.
👌那我写一下,晚点发版了跟你说一声
from ctpersistance.
有劳,多谢!
from ctpersistance.
好了,新版本是179
from ctpersistance.
Hi,大神。
我在使用中又遇到几个问题:
1、我突然发现你添加的这个Api(CTPersistanceTable+Upsert),在方法内部开启了事务去处理。但是其他的CTPersistanceTable的Category,例如CTPersistanceTable+Insert,CTPersistanceTable+Delete,CTPersistanceTable+Update都没有在内部开启事务,而是让调用者自己在DataCenter中去开启事务做的。这里做法的不统一可能会导致我们或者其他使用者嵌套一层事务去做这个Upsert的事情,不知道会不会出什么问题。
2、CTPersistanceTable+Upsert只添加是Upsert单个Record的Api,我想Upsert一个RecordsList,是否循环Upsert单个Record的Api的调用就可以了呢?
3、我在网上有搜到利用SQLite的“REPLACE INTO”语句实现Upsert,我有尝试自己去实现一个CTPersistanceTable+Merge的Category,结果搞不定,放弃了!😂
你看这个是否有必要用上?这有我看过似乎有帮助的一个参考链接https://stackoverflow.com/questions/418898/sqlite-upsert-not-insert-or-replace
from ctpersistance.
-
这个我没测试过,到时候我写个test case来看看会不会有什么问题。开事务主要是因为这个过程是一个完整过程,所以需要作为事务。另外因为它涉及的SQL比较多,开事务能提高一点性能。
-
我开一个新的方法接收record list吧
-
REPLACE INTO和Upsert是不一样的,你给的链接的下面一个回答,就说明了这个问题
from ctpersistance.
好的!静候大神新版本!我这个不急,等你有空再弄就可以了,多谢!
from ctpersistance.
我改了方法,提供了一个参数,用于指定nil要不要被更新入数据库。
-
关于transaction的嵌套,我测试了一下没发现问题。但是我这边没有完整场景,如果transaction中还包含其他的操作,不确定是否会有问题,这个到时候有问题的话我们可以再看。
-
我觉得我不应该提供新方法接收record list,因为两个原因:
一:实现其实就是在transaction中去做遍历,很简单。当前情况的最优化的方案也就是在transaction中遍历,在sqlite场景下,这跟一次性生成N句SQL一次执行性能相差不大。
二:可能list中有的record是需要把nil更新进去的,有的不需要。这个判断需要了解业务的人去做,我底层库没有条件去做。
我给一个针对二的场景:
一个UserRecord,它可能需要更新“自我描述”或者“姓名”
现在你有一个UserRecord列表,里面含有这样两个record:
AUser的自我描述为nil,姓名为“casa”
数据库中AUser的自我描述为“工程师”,姓名是“casatwy”
本次更新目的是更新姓名为casatwy
BUser的自我描述为nil,姓名为“casatwy”。
数据库中BUser的自我描述为“工程师”,姓名是“casatwy”
本次更新的目的是更新自我描述为nil。
因此在遍历UserRecord列表的时候,你需要结合业务去做判断。
当你遍历到AUser的时候,结合业务判断之后,知道调用upsert方法时传的shouldUpdateNilValueToDatabase应该是NO。否则数据库中的“自我描述”就被更新成nil了,这是当前情况不期望的。
当你遍历到BUser的时候,结合业务判断之后,知道调用upsert方法时传的shouldUpdateNilValueToDatabase应该是YES。否则你就没办法把“casatwy”的自我描述更新成nil了,此时upsert就无效了。
from ctpersistance.
新版本180已发
from ctpersistance.
Hi,先感谢下新版本。但是使用中我还是遇到一些问题:
我的Table是这样设计的:
调试得知weakSelf.child.primaryKeyName其实就是table的PrimaryKey,但是我的Record并没有创建这样一个属性。我的Record主键除了PrimaryKey,_id也是主键。既然upsertRecord:uniqKeyName:shouldUpdateNilValueToDatabase: error:这个方法有传递一个uniqKeyName,是否可以[record valueForKey: uniqKeyName]这样子?这样我也无需给Record创建一个PrimaryKey的属性了。(其实PrimaryKey对于我的Record来说没有什么用,最多是了解一下这些record插入进table的顺序。我主要还是用_id做主键,但是SQLite似乎又不能用TEXT做主键。)
from ctpersistance.
我思考一下哦。。。
from ctpersistance.
如果这里我改成了用uniqKeyName去作判断的话,你这里record的uniqKeyName对应的value是没有的,我没办法执行insert操作,因为如果我执行插入的话,uniqKeyName的value就是NULL,再遇到第二个_id也没有值的record的话,就会插入第二个_id也是NULL的record,此时_id就不是uniq了~
from ctpersistance.
你这边_id的来源是什么?是因为你们后端用的mongodb?然后mongodb生成的?
from ctpersistance.
而且如果按照你的做法,在这个场景下是有问题的:
通过primaryKey取出一个record之后,你修改的正好是_id的值,然后你想把它update回去。
此时我根据你的新_id值是找不到那个要更新的record的,最终就没办法update,然后这个就会执行insert
from ctpersistance.
所以primaryKey你还是要在record中给到这个属性的
from ctpersistance.
我的_id是后台服务器给到的,是绝对存在并且唯一的。你提出的这个场景,我觉得我这边不会出现,因为其实我本来是想用_id来做主键的,但是因为SQLite不允许用TEXT做主键,主键又必须存在,所以只好自己建一个primaryKey的列来充当主键,顺便用这个primaryKey来记录一下这些Record的顺序。(如果这种设计有缺陷,还请帮忙纠正一下。)
如果确实需要在record给到primaryKey这个属性,我觉得还是需要用一个protocol去约束一下这个record,强制要求这个record要有primaryKey这个属性。
from ctpersistance.
哦,那你们后端用的应该就是mongodb。
我觉得protocol没有意义,因为primaryKey的名字是table中定义的,无论叫什么名字都是可以的。
建议还是table里面设计了那些column,record里面就给齐,这样比较规范。
from ctpersistance.
Related Issues (20)
- update 操作可能出现问题 HOT 3
- 同样是数据库更新错误 HOT 19
- 更新还是有问题 HOT 1
- 空值对象的改进问题 HOT 1
- CTPersistanceDatabasePool 中的一些问题 HOT 2
- CTPersistanceDataBase没有提供自己定义数据库路径的接口 HOT 3
- 关于bindValueList HOT 1
- 当Table中没有数据的时候,Upsert一个带有PrimaryKey的Record,失败 HOT 1
- 数据库模糊查询findAllWithWhereCondition:@"name LIKE :name",没有数据 HOT 6
- 已有未加密数据库,增加加密功能出错 HOT 8
- 数据库操作偶尔崩溃在executeWithError方法中 HOT 83
- "Include of non-modular header inside framework module" HOT 1
- crash Thread 28: EXC_BAD_ACCESS (code=1, address=0x100000000) HOT 1
- [__NSDictionaryM setObject:forKey:]: object cannot be nil (key: jsonString) crash HOT 3
- 小白问下,表文件创建后能添加新字段吗 HOT 2
- 这个数据库迁移要结合CTMediator这个三方来做吗 HOT 1
- crash:setObjectForKey: object cannot be nil
- 你个博客http://casatwy.com无法打开。求增加字段升级数据库操作文档。 HOT 3
- podfile 文件开启 use_frameworks 后 sqlite3_key 调用系统方法
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ctpersistance.