NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。
整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含多年开发经验于其中,代表作有百亿级大数据实时计算项目。
开源地址:https://github.com/NewLifeX/X (求star, 707+)
前文《XCode添删改》给大家展示了添删改数据的基本概况,本文将详解添删改高级功能。
基本添删改
最常用的添删改操作Insert/Update/Delete,实际是根据实体对象生成相应的SQL语句,由IEntityPersistence接口实现。
** IEntityPersistence在XCode内部有一个默认实现,用户可以自定义后注册到对象容器ObjectContainer中。
添加
Insert 生成标准Insert Into语句,根据设置决定是否使用参数化。(参数化设置)
Insert Into User(Name, Password, DisplayName, Sex, Mail, Mobile, Code, Avatar, RoleID, RoleIDs, DepartmentID, Online, Enable, Logins, LastLogin, LastLoginIP, RegisterTime, RegisterIP, Ex1, Ex2, Ex3, Ex4, Ex5, Ex6, UpdateUser, UpdateUserID, UpdateIP, UpdateTime, Remark) Values('张三', 'E10ADC3949BA59ABBE56E057F20F883E', null, 0, null, null, null, null, 0, null, 0, 0, 0, 0, null, null, null, null, 0, 0, 0, null, null, null, null, 0, null, null, null);Select last_insert_rowid() newid
Insert把所有字段加入到SQL中,即使是没有设置数值的字段,也给予默认值。(自增字段显然不需要加入)
生成的Insert Into语句,最后一部分是获取最近插入的自增ID,因此执行Insert以后,user.ID就取得了最新的自增值。
修改
Update 最精彩的部分,莫过于脏数据(后面将有专门文章介绍)。
在XCode中,修改数据的标准流程是,先查出来,修改属性后保存。此时生成的update set语句,只包含修改过的字段。
Update User Set Mobile='13012345678', Code='abcdef' Where ID=74
如上,修改了3个字段,但是Name本来就是“张三”,因此实际上只修改了两个字段,也就是说只有两个字段有脏数据(数值改变被弄脏了)。
最终生成的update set语句,只包含带有脏数据的字段。最后的where部分,则由主键组成。
删除
Delete 就简单多了,只取了其中的主键字段,拼接where部分。
Delete From User Where ID=74
保存
Save 是一个包装操作,它会根据主键来判断调用Insert或Update。
- 如果实体对象来自数据库,Save时调用Update;
- 自增主键,ID=0时调用Insert,否则调用Update;
- 非自增主键,查询一次数据库,如果有数据则Update,没有则Insert,(这样子显然很傻)
重载添删改
实体类的添删改操作都可以重载(Insert/Update/Delete/OnInsert/OnUpdate/OnDelete)
重载后可以做业务代码判断,也可以级联更新其它表,还可以记录添删改操作日志,甚至还可以做假删除(重载OnDelete然后实际执行OnUpdate)
分为两组重载,实际执行顺序是:Insert=>Valid=>EntityModule=>OnInsert
数据验证Valid
每个实体类在Insert/Update之前,都需要Valid验证数据 ,参数isNew以区分Insert。
Valid常常可用于判断主要字段的有效性,无效时强烈推荐抛出参数类异常,魔方NewLife.Cube表单将可以捕获并定位。
除此之外,Valid用得更多的功能是在Insert/Update之前修改完善字段数据,例如上面对密码进行MD5散列,以及格式化RoleIDs。
这里出现新技术,IsDirty和Dirtys,这是XCode的脏数据,前者判断Password字段是否有脏数据(Password被赋予跟原来不想等的值),后者清空Password脏数据。
脏数据是生成Update语句的核心,不脏的字段不会出现在update set 之中,实现部分字段更新,后续有专门章节讲解。
实体过滤器
实体过滤器EntityModule,用于拦截实体类的添删改操作,内置最常用的3个过滤器UserModule/TimeModule/IPModule
前面《XCode数据模型文件》推荐的8个常用字段还记得吗? CreateUser/CreateTime/CreateIP 等,所有CreateAbc将在Insert的时候拦截赋值,所有UpdateAbc将在Insert和Update的时候拦截赋值。
UserModule取当前登录用户,由ManageProvider驱动;
TimeModule取当前时间;
IPModule取当前访问IP,由ManageProvider.UserHost提供;