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提供;
系列教程
NewLife.XCode教程系列[2019版]
- 增删改查入门。快速展现用法,代码配置连接字符串
- 数据模型文件。建立表格字段和索引,名字以及数据类型规范,推荐字段(时间,用户,IP)
- 实体类详解。数据类业务类,泛型基类,接口
- 功能设置。连接字符串,调试开关,SQL日志,慢日志,参数化,执行超时。代码与配置文件设置,连接字符串局部设置
- 反向工程。自动建立数据库数据表
- 数据初始化。InitData写入初始化数据
- 高级增删改。重载拦截,自增字段,Valid验证,实体模型(时间,用户,IP)
- 脏数据。如何产生,怎么利用
- 增量累加。高并发统计
- 事务处理。单表和多表,不同连接,多种写法
- 扩展属性。多表关联,Map映射
- 高级查询。复杂条件,分页,自定义扩展FieldItem,查总记录数,查汇总统计
- 数据层缓存。Sql缓存,更新机制
- 实体缓存。全表整理缓存,更新机制
- 对象缓存。字典缓存,适用用户等数据较多场景。
- 百亿级性能。字段精炼,索引完备,合理查询,充分利用缓存
- 实体工厂。元数据,通用处理程序
- 角色权限。Membership
- 导入导出。Xml,Json,二进制,网络或文件
- 分表分库。常见拆分逻辑
- 高级统计。聚合统计,分组统计
- 批量写入。批量插入,批量Upsert,异步保存
- 实体队列。写入级缓存,提升性能。
- 备份同步。备份数据,恢复数据,同步数据
- 数据服务。提供RPC接口服务,远程执行查询,例如SQLite网络版
- 大数据分析。ETL抽取,调度计算处理,结果持久化