【ios】基于realm的记账软件--记账模块(一)。
1、数据库表设计
账单表:bill
字段 | 类型 | 说明 |
---|---|---|
billid | nsstring | 账单id,主键 |
date | nsstring | 账单产生日期 |
money | double | 账单金额 |
isincome | bool | true代表收入,false代表支出 |
remark | nsstring | 备注 |
accountid | nsstring | 账户id外键 |
categoryid | nsstring | 类别id外键 |
bookid | nsstring | 账本id外键 |
账单类型表:category
字段 | 类型 | 说明 |
---|---|---|
cateid | nsstring | 账单类型id,主键 |
name | nsstring | 类型名 |
imagename | nsstring | 图标名 |
isincome | bool | true代表收入,false代表支出 |
账户表:account
字段 | 类型 | 说明 |
---|---|---|
accountid | nsstring | 账户id,主键 |
name | nsstring | 类型名 |
money | double | 账户余额 |
账本表:book
字段 | 类型 | 说明 |
---|---|---|
bookid | nsstring | 账本id,主键 |
name | nsstring | 账本名 |
以上,就是该项目的所有数据库表。实际项目会因业务需求,追加一些字段,但核心还是不变的。
2、realm数据库
2.1、概述
realm 是一个跨平台的移动数据库引擎,2014年7月发布,准确来说,它是专门为移动应用所设计的数据持久化解决方案之一。realm可以轻松地移植到您的项目当中,并且绝大部分常用的功能(比如说插入、查询等等)都可以用一行简单的代码轻松完成!
2.2、特点
realm有如下特点:
跨平台:现在绝大多数的应用开发并不仅仅只在ios平台上进行开发,还要兼顾到 android平台的开发。为两个平台设计不同的数据库是愚蠢的,而使用 realm 数据库, ios和android 无需考虑内部数据的架构,调用realm提供的api 就可以完成数据的交换,实现“一个数据库,两个平台无缝衔接 ”。 简单易用:core data 和 sqlite 冗余、繁杂的知识和代码足以吓退绝大多数刚入门的开发者,而换用realm,则可以极大地减少学习代价和学习时间,让应用及早用上数据存储功能。 可视化:realm 还提供了一个轻量级的数据库查看工具,借助这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。毕竟,很多时候,开发者使用数据库的理由是因为要提供一些所谓的“知识库”2.3、基本使用
2.3.1、创建
在realm数据库中,你不需要写任何的sql语句,只需将你的模型继承rlmobject,之后的事情就不需要再管了。
例如,账单表:
/// 账单模型 @interface mpbillmodel : rlmobject /// 账单id @property (nonatomic, copy) nsstring *billid; /// 账单产生日期,要跟recorddate区分开 @property (nonatomic, copy) nsstring *datestr; /// 账单记录日期,指的是生成账单的时间,用于排序 @property (nonatomic, strong) nsdate *recorddate; /// 是否为收入 @property (nonatomic, assign) bool isincome; /// 备注 @property (nonatomic, copy) nsstring *remark; /// 金额 @property (nonatomic, assign) double money; /// 账单类别 @property (nonatomic, strong) mpcategorymodel *category; /// 账户 @property (nonatomic, strong) mpaccountmodel *account; /// 账本 @property (nonatomic, strong) mpbookmodel *book; @end rlm_array_type(mpbillmodel)
在.m文件中指定主键
#import "mpbillmodel.h" @implementation mpbillmodel + (nsstring *)primarykey { return @"billid"; } @end
2.3.2 增删查改
在realm中,你不需要写一句sql语句,即可完成增删查改。除了查询之外,“删增改”等写入操作必须开启事务,否则程序就会崩溃!
查询
realm查询支持以下三种方式:
1、使用断言字符串查询
/// 获得指定账本的所有账单 mpbookmodel *book = [[mpbookmanager sharemanager] getcurrentbook]; rlmresults *results = [mpbillmodel objectswhere:@"book=%@", book];
2、使用 nspredicate 查询:
/// 在指定账本,查询某个月份开头的账单 nspredicate *predicate = [nspredicate predicatewithformat:@"datestr beginswith %@ and book.bookid=%@", datestr, book.bookid]; rlmresults *results = [mpbillmodel objectswithpredicate:predicate];
3、链式查询
例如对插叙后的结果集进行排序,可以分以下两布
/// 获取当前账本的所有账单后,再排序 - (rlmresults *)getbillsincurrentbook { mpbookmodel *book = [[mpbookmanager sharemanager] getcurrentbook]; rlmresults *results = [mpbillmodel objectswhere:@"book=%@", book]; // 返回排序后的结果集 return [self sorttheresultsbydate:results]; } /// 排序 - (rlmresults *)sorttheresultsbydate:(rlmresults *)results { // 首先根据datestr(账单时间)进行排序 rlmsortdescriptor *desc1 = [rlmsortdescriptor sortdescriptorwithkeypath:@"datestr" ascending:no]; // 再根据recorddate(记录时间)进行排序 rlmsortdescriptor *desc2 = [rlmsortdescriptor sortdescriptorwithkeypath:@"recorddate" ascending:no]; return [results sortedresultsusingdescriptors:@[desc1, desc2]]; }
增
对realm数据库进行写入操作时,必须开启事务。开启事务有以下两种方式:
1、分别调用开启和关闭事务
[realm beginwritetransaction]; [realm commitwritetransaction];
2、使用block
rlmrealm *realm = [rlmrealm defaultrealm]; [realm transactionwithblock:^{ // 进行操作 }];
添加有两种方式
//1 、调用realm的addobject rlmrealm *realm = [rlmrealm defaultrealm]; [realm transactionwithblock:^{ // me是rlmobject [realm addobject:me]; }]; //2、调用模型的createindefaultrealmwithvalue方法 [krealm transactionwithblock:^{ [mpbillmodel createindefaultrealmwithvalue:bill]; }]; }
删
直接调用realm的deletobject方法
rlmrealm *realm = [rlmrealm defaultrealm]; [realm transactionwithblock:^{ [realm deleteobject:bill]; }];
修改
修改内容只要开启事务后,直接拿对象做操作即可
/// 将账单的金额改为999 rlmrealm *realm = [rlmrealm defaultrealm]; [realm transactionwithblock:^{ bill.money = 999 }];
2.3.3、主键的创建
由于realm是不支持id自增的,如果要实现id自增,需要自己实现,并且性能会不好。因此,在这里,我们需要给每一个字段创建一个独一无二的id。
那么,我们可以通过nsuuid产生主键,方法如下:
// myutils.m /** 创建主键 @return 主键 */ + (nsstring *)createkey { nsuuid *uid = [nsuuid uuid]; return uid.uuidstring; }
2.3.4、注意
当你的数据模型发生变化时,需要调用以下代码进行数据库迁移。建议在appdelegate中的 didfinishlaunchingwithoptions调用
/// 数据库版本检测 - (void)dbversioncheck { rlmrealmconfiguration *config = [rlmrealmconfiguration defaultconfiguration]; // 设置新的架构版本。这个版本号必须高于之前所用的版本号(如果您之前从未设置过架构版本,那么这个版本号设置为 0) config.schemaversion = 1; // 设置闭包,这个闭包将会在打开低于上面所设置版本号的 realm 数据库的时候被自动调用 config.migrationblock = ^(rlmmigration *migration, uint64_t oldschemaversion) { // 目前我们还未进行数据迁移,因此 oldschemaversion == 0 if (oldschemaversion < 1) { // 什么都不要做!realm 会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构 } }; // 告诉 realm 为默认的 realm 数据库使用这个新的配置对象 [rlmrealmconfiguration setdefaultconfiguration:config]; // 现在我们已经告诉了 realm 如何处理架构的变化,打开文件之后将会自动执行迁移 [rlmrealm defaultrealm]; }
3、realm browser
realm提供了一个专门用于查看realm数据库的可视化工具—realm browse。在app store即可进行下载~只需要打印出沙盒路径后,找到doucument下的realm文件即可查看。若查看失败,请留意一下realm库的版本与realm browser的版本(一般最新的realm库,需要新版的realm browser才能查看)。
4、小结
在本文中,对项目所要使用的数据表列出来了,以及简单介绍了realm的使用。建议大家在使用前建个小demo体验一下~
您可能感兴趣的文章:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论