首页 文章 精选 留言 我的

精选列表

搜索[库存盘点],共4441篇文章
优秀的个人博客,低调大师

iOS - SQLite 数据库存储

1、SQLite 数据库 SQLite 是一种轻型的嵌入式数据库,安卓和 iOS 开发使用的都是 SQLite 数据库。它占用资源非常低,在嵌入式设备中,可能需要几百 K 的内存数据就够了。他的处理速度比 Mysql、PostgreSQL 这两款著名的数据库都要快。数据库的存储和 Excel 很像,以表(table)为单位。表由多个字段(列、属性、column)组成,表里面的每一行数据称为记录。数据库操作包含打开数据库、创建表,表的增、删、改、查。 SQL(Structured Query Language)结构化查询语言,SQL 是一种对数据库中的数据进行定义和操作的语言。使用 SQL 语言编写出来的句子/代码叫 SQL 语句,在程序运行过程中,想要操作(增删改查,CRUD)数据库中的数据,必须使用 SQL 语句。SQL 语句不区分大小写,每句语句都必须以分号结尾。 SQL 中常用的关键字有 select、insert、update、delete、from、create、where、desc、orderby、table,数据库中不可以使用关键字来命名表、字段。SQL 语句中用 ?来作为占位符,不管字段是何种类型。 SQLite 语句的种类: 数据定义语句(DDL:Data Definition Language):包括 create 和 drop 等操作,在数据库中创建新表或删除表(create table 或 drop table)。 数据操作语句(DML:Data Manipulation Language):包括 insert、update、delete 等操作,上面的三种操作分别用于添加、修改、删除表中的数据。 数据查询语句(DQL:Data Query Language):可以用于查询获得表中的数据,关键字 select 是 SQL(也是所有 SQL)用的最多的操作,其他 DQL 常用的关键字有 where、order by、group by 和 having。 注意:写入数据库,字符串可以采用 char 方式,而从数据库中取出 char 类型,当 char 类型有表示中文字符时,会出现乱码。这是因为数据库默认使用 ASCII 编码方式。所以要想正确从数据库中取出中文,需要用 NSString 来接收从数据库取出的字符串。 SQLite 操作方法 sqlite3 *db 数据库句柄,跟文件句柄很类似 sqlite3_stmt *stmt 这个相当于 ODBC 的 Command 对象,用于保存编译好的 SQL 语句 sqlite3_open() 打开数据库,没有数据库时创建。 sqlite3_exec() 执行非查询的 sql 语句 sqlite3_prepare_v2 执行查询的 sql 语句 Sqlite3_step() 在调用 sqlite3_prepare 后,使用这个函数在记录集中移动。 sqlite3_free() 清空变量 Sqlite3_close() 关闭数据库文件 还有一系列的函数,用于从记录集字段中获取数据,如: sqlite3_column_text() 取 text 类型的数据。 sqlite3_column_blob() 取 blob 类型的数据 sqlite3_column_int() 取 int 类型的数据 SQLite 命令行 .help :帮助 .quit :退出 .database:列出数据库信息 .dump :查看所有的 sql 语句 .schema :查看表结构 .tables :显示所有的表 SQL 语句常用数据类型 (1)整型: bigint :整形数据,大小为 8 个字节 integer :整形数据,大小为 4 个字节 smallint:整形数据,大小为 2 个字节 tinyint :从 0 到 255 的整形数据,存储大小为 1 字节 (2)浮点型: float :4 字节浮点数 double:8 字节浮点数 real :8 字节浮点数 (3)字符型: char(n) :n 长度的字串,n 不能超过 254 varchar(n):长度不固定且其长度为 n 的字串,n 不能超过 4000 text :text 存储可变长度的非 unicode 数据,存放比 varchar 更大的字符串 注意事项: 尽量用 varchar 超过 255 字节的只能用 varchar 或 text 能用 varchar 的地方不用 text SQLite 字符串区别: char 存储定长数据很方便,char 字段上的索引效率极高,比如定义 char(10),那么不论你存储的数据是否达到了 10 个字节,都要占去 10 个字节的空间,不足的自动用空格填充。 varchar 存储变长数据,但存储效率没有 char 高,如果一个字段可能的值是不固定长度的,我们只知道它不可能超过 10 个 > 字符,把它定义为 varchar(10) 是最合算的,varchar 类型的实际长度是它的值的实际长度 +1,为什么 +1 呢 ?这个字节用于保存实际使用了多大的长度。因此,从空间上考虑,用 varchar 合适,从效率上考虑,用 char 合适,关键是根据情况找到权衡点。 text 存储可变长度的非 Unicode 数据,最大长度为 2^31-1(2147483647)个字符。 (4)日期类型: date :包含了年份,月份,日期 time :包含了小时,分钟,秒 datetime :包含了年,月,日,时,分,秒 timestamp:包含了年,月,日,时,分,秒,千分之一秒 注意:datetime 包含日期时间格式,必须写成 ‘2010-08-05’不能写为‘2010-8-5’,否则在读取时会产生错误。 (5)其他类型: null :空值 blob :二进制对象,主要用来存放图片和声音文件等 default :缺省值 primary key :主键值 autoincrement:主键自动增长 (6)什么是主键: primary key,主键就是一个表中,有一个字段,里面的内容不可以重复,一般一个表都需要设置一个主键,autoincrement 让主键自动增长。 (7)注意事项: 所有字符串必须要加 ‘ ’ 单引号 整数和浮点数不用加 ‘ ’ 日期需要加单引号 ‘ ’ 字段顺序没有关系,关键是 key 与 value 要对应 对于自动增长的主键不需要插入字段 简单基本的 SQL 语句 (1) 数据记录筛选: sql="select * from 数据表 where 字段名=字段值 order by 字段名 [desc]" sql="select * from 数据表 where 字段名 like '%字段值%' order by 字段名 [desc]" sql="select top 10 * from 数据表 where 字段名=字段值 order by 字段名 [desc]" sql="select top 10 * from 数据表 order by 字段名 [desc]" sql="select * from 数据表 where 字段名 in ('值1','值2','值3')" sql="select * from 数据表 where 字段名 between 值1 and 值2" (2) 更新数据记录: sql="update 数据表 set 字段名=字段值 where 条件表达式" sql="update 数据表 set 字段1=值1,字段2=值2 …… 字段n=值n where 条件表达式" (3) 删除数据记录: sql="delete from 数据表 where 条件表达式" sql="delete from 数据表" (将数据表所有记录删除) (4) 添加数据记录: sql="insert into 数据表 (字段1,字段2,字段3 …) values (值1,值2,值3 …)" sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到目标数据表) (5) 数据记录统计函数: AVG(字段名) 得出一个表格栏平均值 COUNT(*;字段名) 对数据行数的统计或对某一栏有值的数据行数统计 MAX(字段名) 取得一个表格栏最大的值 MIN(字段名) 取得一个表格栏最小的值 SUM(字段名) 把数据栏的值相加 引用以上函数的方法: sql="select sum(字段名) as 别名 from 数据表 where 条件表达式" //set rs=conn.excute(sql) 用 rs("别名") 获取统计的值,其它函数运用同上。 查询去除重复值:select distinct * from table1 (6) 数据表的建立和删除: CREATE TABLE 数据表名称(字段1 类型1(长度),字段2 类型2(长度) …… ) 2、iOS 自带 SQLite 的使用 1、环境配置 在 TARGETS => Build Phases => Link Binary With Libraries => 中添加:libsqlite3.0.tbd 或者在 TARGETS => Build Settings => Linking => Other Linker Flags 中添加 -l< 所需 dylib 的名称 >:-lsqlite3.0 2、使用 添加头文件: #import "sqlite3.h" 配置数据库路径 // 设置数据库文件路径 NSString *databaseFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"mydb.sqlite"]; // 创建数据库句柄 sqlite3 *db; // 错误记录 char *error; 3、打开数据库 // 数据库文件不存在时,自动创建文件 if (sqlite3_open([databaseFilePath UTF8String], &db) == SQLITE_OK) { NSLog(@"sqlite dadabase is opened."); } else { NSLog(@"sqlite dadabase open fail."); } 4、创建数据表 /* sql 语句,专门用来操作数据库的语句。 create table if not exists 是固定的,如果表不存在就创建。 myTable() 表示一个表,myTable 是表名,小括号里是字段信息。 字段之间用逗号隔开,每一个字段的第一个单词是字段名,第二个单词是数据类型,primary key 代表主键,autoincrement 是自增。 */ // create table if not exists 表名(主键名 主键类型 primary key autoincrement, 键名 键类型, 键名 键类型, ...) NSString *createSql = @"create table if not exists myTable(id integer primary key autoincrement, name text, age integer, address text)"; if (sqlite3_exec(db, [createSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"create table is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 5、插入记录 // insert into 表名(键名, 键名, ...) values('键值', '键值', '...') NSString *insertSql = @"insert into myTable(name, age, address) values('小新', '8', '东城区')"; if (sqlite3_exec(db, [insertSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"insert operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 6、删除记录 // delete from 表名 查询条件(where id = 2) NSString *deleteSql = @"delete from myTable where id = 2"; if (sqlite3_exec(db, [deleteSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"delete operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 7、修改记录 // update 表名 set 键名 = '键值', 键名 = '键值', ... 查询条件(where id = 3) NSString *updateSql = @"update myTable set name = '小白', age = '10', address = '西城区' where id = 3"; if (sqlite3_exec(db, [updateSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"update operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 8、查询记录 sqlite3_stmt *statement; // select 键名, 键名, ... from 表名,select * from 表名:查询所有 key 值内容 NSString *selectSql = @"select id, name, age, address from myTable"; if (sqlite3_prepare_v2(db, [selectSql UTF8String], -1, &statement, nil) == SQLITE_OK) { while(sqlite3_step(statement) == SQLITE_ROW) { // 查询 id 的值 int _id = sqlite3_column_int(statement, 0); // 查询 name 的值 NSString *name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]; // 查询 age int age = sqlite3_column_int(statement, 2); // 查询 address 的值 NSString *address = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 3)]; NSLog(@"id: %i, name: %@, age: %i, address: %@", _id, name, age, address); } } else { NSLog(@"select operation is fail."); } sqlite3_finalize(statement); 9、关闭数据库 if (sqlite3_close(db) == SQLITE_OK) { NSLog(@"sqlite dadabase is closed."); } else { NSLog(@"sqlite dadabase close fail."); } 3、fmdb 的使用 iOS 中原生的 SQLite API 在使用上相当不友好,在使用时,非常不便。于是,就出现了一系列将 SQLite API 进行封装的库,例如 fmdb、PlausibleDatabase、sqlitepersistentobjects 等,fmdb 是一款简洁、易用的封装库。 fmdb 同时兼容 ARC 和非 ARC 工程,会自动根据工程配置来调整相关的内存管理代码。 fmdb 常用类: FMDatabase : 一个单一的 SQLite 数据库,用于执行 SQL 语句。 FMResultSet :执行查询一个 FMDatabase 结果集,这个和 Android 的 Cursor 类似。 FMDatabaseQueue :在多个线程来执行查询和更新时会使用这个类。 除了查询操作,fmdb 数据库操作都执行 executeUpdate 方法,这个方法返回 BOOL 型。后面跟的参数类型必须是对象类型,FMDataBase 对象会将传过来的参数,转化成与数据库字段相匹配的类型,再进行后续处理。 fmdb 数据库中查询操作使用 executeQuery,并涉及到 FMResultSet,FMResultSet 提供了多个方法来获取不同类型的数据。 1、环境配置 将 第三方框架 fmdb 添加到工程中,并在 TARGETS => Build Phases => Link Binary With Libraries => 中添加:libsqlite3.0.tbd 2、使用 添加头文件: #import "FMDB.h" 配置数据库路径 // 设置数据库文件路径 NSString *databaseFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"mydb.sqlite"]; // 声明数据库管理对象 @property (nonatomic, strong) FMDatabase *db; // 实例化数据库管理对象 /* 使用数据库的路径初始化 当数据库文件不存在时,fmdb 会自己创建一个。 如果你传入的参数是空串:@"" ,则fmdb会在临时文件目录下创建这个数据库,数据库断开连接时,数据库文件被删除。 如果你传入的参数是 NULL,则它会建立一个在内存中的数据库,数据库断开连接时,数据库文件被删除。 */ self.db = [[FMDatabase alloc] initWithPath:databaseFilePath]; 3、打开数据库 if ([self.db open]) { NSLog(@"sqlite dadabase is opened."); } else { NSLog(@"sqlite dadabase open fail."); } 4、创建数据表 /* sql 语句,专门用来操作数据库的语句 create table if not exists 是固定的,如果表不存在就创建 userInfo() 表示一个表,userInfo 是表名,小括号里是字段信息 字段之间用逗号隔开,每一个字段的第一个单词是字段名,第二个单词是数据类型,primary key 代表主键,autoincrement 是自增 */ // create table if not exists 表名(主键名 主键类型 primary key autoincrement, 键名 键类型, 键名 键类型, ...) NSString *createSql = @"create table if not exists myTable(id integer primary key autoincrement, name text, age integer, address text)"; if ([self.db executeUpdate:createSql]) { NSLog(@"create table is ok."); } else { NSLog(@"create error = %@", self.db.lastErrorMessage); } 5、插入记录 // insert into 表名(键名, 键名, ...) values('键值', '键值', '...') NSString *insertSql = @"insert into myTable(name, age, address) values('小新', '8', '东城区')"; if ([self.db executeUpdate:insertSql]) { NSLog(@"insert operation is ok."); } else { NSLog(@"insert error = %@", self.db.lastErrorMessage); } 6、删除记录 // delete from 表名 查询条件(where id = 2) NSString *deleteSql = @"delete from myTable where id = 2"; if ([self.db executeUpdate:deleteSql]) { NSLog(@"delete operation is ok."); } else { NSLog(@"delete error = %@", self.db.lastErrorMessage); } 7、修改记录 // update 表名 set 键名 = '键值', 键名 = '键值', ... 查询条件(where id = 3) NSString *updateSql = @"update myTable set name = '小白', age = '10', address = '西城区' where id = 3"; if ([self.db executeUpdate:updateSql]) { NSLog(@"update operation is ok."); } else { NSLog(@"update error = %@", self.db.lastErrorMessage); } 8、查询记录 // select 键名, 键名, ... from 表名,select * from 表名:查询所有 key 值内容 NSString *selectSql = @"select id, name, age, address from myTable"; // FMResultSet 查询结果,执行查询 SQL 语句 FMResultSet *set = [self.db executeQuery:selectSql]; // 类似于数组的快速遍历,set 会依次代表所有查询出来的数据,每次取出一整条数据,根据字段名称,取出字段的值,将查询到的数据转成模型 while ([set next]) { // 查询 id 的值 int _id = [set intForColumn:@"id"]; // 查询 name 的值 NSString *name = [set stringForColumn:@"name"]; // 查询 age int age = [set intForColumn:@"age"]; // 查询 address 的值 NSString *address = [set stringForColumn:@"address"]; NSLog(@"id: %i, name: %@, age: %i, address: %@", _id, name, age, address); } 9、关闭数据库 if ([self.db close]) { NSLog(@"sqlite dadabase is closed."); } else { NSLog(@"sqlite dadabase close fail."); } 4、fmdb 多线程操作 如果应用中使用了多线程操作数据库,那么就需要使用 FMDatabaseQueue 来保证线程安全了。 应用中不可在多个线程中共同使用一个 FMDatabase 对象操作数据库,这样会引起数据库数据混乱。为了多线程操作数据库安全,fmdb 使用了 FMDatabaseQueue,使用 FMDatabaseQueue 很简单,首先用一个数据库文件地址来初使化 FMDatabaseQueue,然后就可以将一个闭包(block)传入 inDatabase 方法中。在闭包中操作数据库,而不直接参与 FMDatabase 的管理。 // 设置数据库文件路径 NSString *databaseFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"mydb.sqlite"]; // 打开数据库 FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:databaseFilePath]; // 队列 1 dispatch_async(dispatch_queue_create("queue1", NULL), ^{ for (int i = 0; i < 50; ++i) { // 对数据库进行操作,操作完成后会自动关闭数据库 [dbQueue inDatabase:^(FMDatabase *db) { NSString *insertSql= [NSString stringWithFormat: @"insert into myTable(name, age, address) values('%@', '%d', '%@')", @"小新", i, @"东城区"]; if ([db executeUpdate:insertSql]) { NSLog(@"%@ insert queue1 %d operation is ok.", [NSThread currentThread], i); } else { NSLog(@"insert error = %@", db.lastErrorMessage); } }]; } }); // 队列 2 dispatch_async(dispatch_queue_create("queue2", NULL), ^{ for (int i = 0; i < 50; ++i) { // 对数据库进行操作,操作完成后会自动关闭数据库 [dbQueue inDatabase:^(FMDatabase *db) { NSString *insertSql= [NSString stringWithFormat: @"insert into myTable(name, age, address) values('%@', '%d', '%@')", @"小白", i, @"西城区"]; if ([db executeUpdate:insertSql]) { NSLog(@"%@ insert queue2 %d operation is ok.", [NSThread currentThread], i); } else { NSLog(@"insert error = %@", db.lastErrorMessage); } }]; } }); 5、其他 SQLite 的第三方封装库 1、PlausibleDatabase 也是一个数据库操作的 objective-c 版封装库,“SQLite is the initial and primary target, but the API has been designed to support more traditional databases.” 文件较多,一般的接口与 FMDataBase 一样,此外还支持 SQL 的预编译和参数绑定。 2、sqlitepersistentobjects 这个开源库的目标是以面对对象的方式的存储和加载数据,让对象本身就有 save 和 load 的功能,屏蔽数据库的相关操作(创建、更新等),让使用者在不写 SQL 语句的状况下都可以使用 SQLite。应该说是符合 ActiveRecored 标准的。 自从 iOS3.0 支持 Core Data 之后,sqlitepersistentobjects 就停止了更新。不过单从操作数据来说,这个库还是很优秀的,如果你的数据存储工作很简单(light),使用 Core Data 比较显得凝重的话,sqlitepersistentobjects 也许是个很好的选择。

优秀的个人博客,低调大师

iOS - CoreData 数据库存储

1、CoreData 数据库 CoreData 是 iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据。使用 CoreData 框架,程序员可以很轻松有效地通过面向对象的接口管理数据。CoreData 框架提供了 对象 - 关系映射 (ORM) 的功能,即能够将 OC 对象转化成数据,保存在 SQLite3 数据库文件中,也能够将保存在数据库中的数据还原成 OC 对象,在数据操作过程中,无需编写任何 SQL 语句。 模型文件及实体(Entity)。要使用 CodeData,首先需要定义模型文件,描述应用程序中的所有实体(Entities),所谓实体是跟数据库进行映射的对象。 NSManagedObject:对应数据库中的一条记录。 CoreData 主要对象关系示意图类似于数据库的句柄,handle,用来操纵数据库 持久化存储调度者,是数据库与对象之间的,在开发中。只会用到一次,如果不理解,直接粘代码。 CoreData 主要对象 NSManagedObjectContext:负责应用和数据库之间的交互 (CRUD)。 NSPersistentStoreCoordinator:添加持久化存储库(如 SQLite 数据库), 是物理数据存储的物理文件和程序之间的联系的桥梁 ,负责管理不同对象上下文。 NSManagedObjectModel:被管理的对象模型。 NSEntityDescription:实体描述。 2、CoreData 的使用 配置 1、在工程中新建 Data Model 数据模型文件。 2、在 Data Model 模型文件中添加 Entity 实体,修改实体名称,并在实体中添加模型属性。 3、在模型文件右侧属性列表的 Code Generation 中设置生成 NSManagedObject subclass 子类的使用语言。 4、在模型文件右侧属性列表的 Class => Codegen 中设置 Manual/None。如果不修改此项程序编译时会报 Linker command failed with exit code 1 (use -v to see invocation) 错误。 5、基于 Data Model 数据库文件中的 Entity 创建 NSManagedObject subclass 类。Xcode8 从系统菜单的 Editor 创建,创建后文件中多出来 4 个文件。 6、在需要使用 CoreData 的文件中。 // 引入头文件 #import "Student+CoreDataClass.h" // 宏定义实体(数据表)名称 #define ENTITY_STUDENT @"Student" 搭建 CoreData 环境 // 声明目标对象上下文,CoreData 操作数据的环境 @property (nonatomic, strong) NSManagedObjectContext *moc; // 托管对象模型文件路径 NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"TestModel" ofType:@"momd"]; NSURL *modelUrl = [NSURL fileURLWithPath:modelPath]; // 创建托管对象模型,CoreData 数据模型文件 NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl]; // 创建持久化存储协调器,处理数据的读写 NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; // SQLite 数据库文件路径,CoreData 使用的数据库文件后缀一般写 sqlite NSString *sqlPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"student.sqlite"]; NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath]; NSLog(@"sqlPath:%@", sqlPath); // 将 CoreData 文件映射到数据库,并判断操作状态 NSError *error = nil; NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:&error]; if (!store) { NSLog(@"addError = %@", error); } // 创建操作数据的对象 self.moc = [[NSManagedObjectContext alloc] init]; // 关联持久化存储协调器 self.moc.persistentStoreCoordinator = coordinator; 插入数据 // 获取插入到实体的指针 Student *std = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_STUDENT inManagedObjectContext:self.moc]; // 赋值 std.name = self.nameTF.text; std.age = self.ageTF.text.intValue; NSError *error = nil; // 同步到数据库并判断 if ([self.moc save:&error]) { [self.myDataArray addObject:std]; [self.myTableView reloadData]; } else { NSLog(@"insert error = %@", error); } 删除数据 // 获取要删除的数据 Student *std = self.myDataArray[self.selectedRow]; // 从实体中删除 [self.moc deleteObject:std]; NSError *error = nil; // 同步到数据库并判断 if ([self.moc save:&error]) { [self.myDataArray removeObjectAtIndex:self.selectedRow]; [self.myTableView reloadData]; } else { NSLog(@"delete error = %@", error); } 修改数据 // 获取要修改的数据 Student *dent = self.myDataArray[self.selectedRow]; // 赋值 dent.name = self.nameTF.text; dent.age = self.ageTF.text.intValue; NSError *error = nil; // 同步到数据库并判断 if ([self.moc save:&error]) { [self.myTableView reloadData]; } else { NSLog(@"update error = %@", error); } 查询数据 // 查询请求 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT]; // 查询条件(正则表达式),name 以某些字符开头 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", [NSString stringWithFormat:@"%@*", self.nameTF.text]]; // 设置请求条件,如果不设查询条件会查询所有 request.predicate = predicate; NSError *error = nil; // 执行查询 self.myDataArray.array = [self.moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"fech = %@", error); } else { [self.myTableView reloadData]; } // 查询所有 CoreData 数据 // 查询请求 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT]; NSError *error = nil; // 查询 NSArray *tmpArray = [self.moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"fech = %@", error); } else { // 将查询结果存储到数据源数组中 [self.myDataArray setArray:tmpArray]; [self.myTableView reloadData]; } 3、MagicalRecord 的使用 CoreData 是 iOS 开发中经常使用的数据持久化的技术。但其操作过程稍微繁琐,即使你只是实现简单的存取,不涉及请求优化,也要进行许多配置工作,代码量在动辄几十行,对新手来说也需要较大时间成本。 MagicalRecord 是 OC 的一个库,协助方便 CoreData 的工作。其吸收了 Ruby on Rails 的 Active Record 模式,目标是: 简化 Core Data 相关代码 允许清晰,简单,单行获取 当需要优化请求的时候,仍然允许修改 NSFetchRequest 如果你在使用 MagicalRecord 方法的时候不想带 MR_ 前缀,直接用 findAll 代替 MR_findAll,就在引入头文件 CoreData+MagicalRecord.h 之前增加 #define MR_SHORTHAND 即可。 配置 创建 Model。创建一个 Model.xcdatamodeld ,添加一个 Person Entity,添加 age firstname lastname 三个属性。最后使用 Editor => Create NSManagedObject Subclass ORM 生成 Person 类。 在使用的文件中引入头文件 // 添加宏定义 #define MR_SHORTHAND // 引入头文件 #import "MagicalRecord.h" 初始化 - (void)viewDidLoad { [super viewDidLoad]; // 初始化 [MagicalRecord setupCoreDataStackWithStoreNamed:@"Model.sqlite"]; } - (void)dealloc { // 清理 [MagicalRecord cleanUp]; } 增 Person *person = [Person MR_createEntity]; person.firstname = @"Frank"; person.lastname = @"Zhang"; person.age = 26; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 删 Person *person = ...; // 此处略,取出的数据模型 [person MR_deleteEntity]; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 改 Person *person = ...; // 此处略,取出的数据模型 person.lastname = object; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 查 // 查找数据库中的所有 Person。 NSArray *persons = [Person MR_findAll]; // 查找所有的 Person 并按照 first name 排序。 NSArray *personsSorted = [Person MR_findAllSortedBy:@"firstname" ascending:YES]; // 查找所有 age 属性为 25 的 Person 记录。 NSArray *personsAgeEuqals25 = [Person MR_findByAttribute:@"age" withValue:[NSNumber numberWithInt:25]]; // 查找数据库中的第一条记录 Person *person = [Person MR_findFirst];

优秀的个人博客,低调大师

iOS - OC SQLite 数据库存储

前言 采用 SQLite 数据库来存储数据。SQLite 作为一中小型数据库,应用 iOS 中,跟前三种保存方式相比,相对比较复杂一些。 注意:写入数据库,字符串可以采用 char 方式,而从数据库中取出 char 类型,当 char 类型有表示中文字符时,会出现乱码。这是因为数据库默认使用 ASCII 编码方式。所以要想正确从数据库中取出中文,需要用 NSString 来接收从数据库取出的字符串。 sqlite 的方法: sqlite3 *db 数据库句柄,跟文件句柄很类似 sqlite3_stmt *stmt 这个相当于 ODBC 的 Command 对象,用于保存编译好的 SQL 语句 sqlite3_open() 打开数据库,没有数据库时创建。 sqlite3_exec() 执行非查询的 sql 语句 Sqlite3_step() 在调用 sqlite3_prepare 后,使用这个函数在记录集中移动。 Sqlite3_close() 关闭数据库文件 还有一系列的函数,用于从记录集字段中获取数据,如: sqlite3_column_text() 取 text 类型的数据。 sqlite3_column_blob() 取 blob 类型的数据 sqlite3_column_int() 取 int 类型的数据 1、环境配置 添加动态库 在 TARGETS => Build Phases => Link Binary With Libraries => +(添加) => Add Other... => command + shit + g => 输入 /usr/lib 找到一下文件并添加:libsqlite3.0.dylib 或者在 TARGETS -> Build Settings -> Linking -> Other Linker Flags 中添加 -l< 所需 dylib 的名称 >:-lsqlite3.0 添加头文件: #import "sqlite3.h" 配置数据库路径 // 设置数据库文件路径 NSString *databaseFilePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/mydb.sqlite"]; // 创建数据库句柄 sqlite3 *db; char *error; 2、打开数据库 // 打开数据库,数据库文件不存在时,自动创建文件 if (sqlite3_open([databaseFilePath UTF8String], &db) == SQLITE_OK) { NSLog(@"sqlite dadabase is opened."); } else { NSLog(@"sqlite dadabase open fail."); } 3、创建数据表 /* sql 语句,专门用来操作数据库的语句。 create table if not exists 是固定的,如果表不存在就创建。 myTable() 表示一个表,myTable 是表名,小括号里是字段信息。 字段之间用逗号隔开,每一个字段的第一个单词是字段名,第二个单词是数据类型,primary key 代表主键,autoincrement 是自增。 */ NSString *createSql = @"create table if not exists myTable(id integer primary key autoincrement, name text, age integer, address text)"; if (sqlite3_exec(db, [createSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"create table is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 4、插入记录 NSString *insertSql = @"insert into myTable(name, age, address) values('小新', '8', '东城区')"; if (sqlite3_exec(db, [insertSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"insert operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 5、修改记录 NSString *updateSql = @"update myTable set name = '小白', age = '10', address = '西城区' where id = 2"; if (sqlite3_exec(db, [updateSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"update operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 6、删除记录 NSString *deleteSql = @"delete from myTable where id = 3"; if (sqlite3_exec(db, [deleteSql UTF8String], NULL, NULL, &error) == SQLITE_OK) { NSLog(@"delete operation is ok."); } else { NSLog(@"error: %s", error); // 每次使用完毕清空 error 字符串,提供给下一次使用 sqlite3_free(error); } 7、查询记录 sqlite3_stmt *statement; // @"select * from myTable" 查询所有 key 值内容 NSString *selectSql = @"select id, name, age, address from myTable"; if (sqlite3_prepare_v2(db, [selectSql UTF8String], -1, &statement, nil) == SQLITE_OK) { while(sqlite3_step(statement) == SQLITE_ROW) { // 查询 id 的值 int _id = sqlite3_column_int(statement, 0); // 查询 name 的值 NSString *name = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)]; // 查询 age int age = sqlite3_column_int(statement, 2); // 查询 name 的值 NSString *address = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 3)]; NSLog(@"id: %i, name: %@, age: %i, address: %@", _id, name, age, address); } } else { NSLog(@"select operation is fail."); } sqlite3_finalize(statement); 8、关闭数据库 sqlite3_close(db);

优秀的个人博客,低调大师

iOS - Swift SQLite 数据库存储

前言 采用 SQLite 数据库来存储数据。SQLite 作为一中小型数据库,应用 iOS 中,跟前三种保存方式相比,相对比较复杂一些。 注意:写入数据库,字符串可以采用 char 方式,而从数据库中取出 char 类型,当 char 类型有表示中文字符时,会出现乱码。这是因为数据库默认使用 ASCII 编码方式。所以要想正确从数据库中取出中文,需要用 NSString 来接收从数据库取出的字符串。 sqlite 的方法: sqlite3 *db 数据库句柄,跟文件句柄很类似 sqlite3_stmt *stmt 这个相当于 ODBC 的 Command 对象,用于保存编译好的 SQL 语句 sqlite3_open() 打开数据库,没有数据库时创建。 sqlite3_exec() 执行非查询的 sql 语句 Sqlite3_step() 在调用 sqlite3_prepare 后,使用这个函数在记录集中移动。 Sqlite3_close() 关闭数据库文件 还有一系列的函数,用于从记录集字段中获取数据,如: sqlite3_column_text() 取 text 类型的数据。 sqlite3_column_blob() 取 blob 类型的数据 sqlite3_column_int() 取 int 类型的数据

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册