持久化存储 --- SQLite3 的基础
一、为什么要使用SQLite3,什么是SQLite3,常见的数据库可以用于移动端嘛?
1、持久化存储的方式有以下几种:
1 2 3 4 5 | 1、plist 只能存储NSDictionary 和NSArray的数据。 2、Preference 偏好设置NSUserDefaults,存取方便,但只能存储小数据。 3、NSCoding (NSKeyedArchiver\NSkeyedUnarchiver)归档可以存储大数据,但是不方便存取,每次存储都会覆盖上一次的内容。 4、SQLite3 重点,存储速度快,而且可以存储大数据且取数据比较方便,可以取出单条数据。 5、Core Data 是对SQLite3的封装。 |
2、什么是SQLite3,有什么优点?
1 2 3 4 5 | 1) SQLite的优点 SQLite是一款轻型的嵌入式数据库 它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了 它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快 2)什么是数据库?<br><br>数据库(Database)是按照数据结构来组织、存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) 对象型数据库 3)常用的数据库有哪些? 常用关系型数据库 PC端:Oracle、MySQL、SQL Server、Access、DB2、Sybase 嵌入式\移动客户端:SQLite 4)如何存储数据 数据库是如何存储数据的 数据库的存储结构和excel很像,以表(table)为单位 数据库存储数据的步骤 1.新建一张表(table) 2. 添加多个字段(column,列,属性) 3.添加多行记录(row,每行存放多个字段对应的值) |
二、SQLite3能做什么?
1、SQLite3能做什么?
1 2 3 | 1、可以存储大量的数据,且通过多线程来保证存取数据的安全,如(用新建一个事务,来解决存取钱中间出出现差错的解决)。 2、可以做离线缓存,方便用户在没有网络且上次已经浏览过的信息,不用再请求网络。 3、可以做本地模糊查询,快速实现用户查询的内容。 |
2、常用的图形化工具是什么?
Navicat Premium图形化软件是mac系统上数据库操作软件
1)打开SQLite3数据库
2)创建一个新的数据库
3)图形化创建表
4)手动写sql的语句
三、如何使用SQLite3?
1、sql语句
1 2 3 4 5 6 7 8 | 使用SQL语言编写出来的句子代码,就是SQL语句 在程序运行过程中,要想操作(增删改查,CRUD)数据库中的数据,必须使用SQL语句 SQL语句的特点 不区分大小写(比如数据库认为user和UsEr是一样的) 每条语句都必须以分号 ; 结尾 SQL中的常用关键字有 select 、insert、update、delete、 from 、create、 where 、desc、order、 by 、 group 、table、alter、view、index等等 数据库中不可以使用关键字来命名表、字段 |
1)数据定义DDL
1 2 3 4 5 | 数据定义语句(DDL:Data Definition Language) 包括create和drop等操作 在数据库中创建新表或删除表(create table或 drop table) 操作注意:只有 crete 和drop 后面需要加上table,然后再跟上表名,其它关键字后面只需要加表名。 |
2) 数据操作DML
1 2 3 | 数据操作语句(DML:Data Manipulation Language) 包括insert、update、delete等操作 上面的3种操作分别用于添加、修改、删除表中的数据 |
3) 数据查询DQL
1 2 3 4 | 数据查询语句(DQL:Data Query Language) 可以用于查询获得表中的数据 关键字 select 是DQL(也是所有SQL)用得最多的操作 其他DQL常用的关键字有 where ,order by , group by 和having |
4)sql常用的数据类型,和注意事项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 注意:字符型数据必须开单引号包起来如,‘%@’,‘The’ SQLite将数据划分为以下几种存储类型: integer : 整型值 real : 浮点值 text : 文本字符串 blob : 二进制数据(比如文件) 实际上SQLite是无类型的 就算声明为integer类型,还是能存储字符串文本(主键除外) 建表时声明啥类型或者不声明类型都可以,也就意味着创表语句可以这么写: create table t_student(name, age); 为了保持良好的编程规范、方便程序员之间的交流,编写建表语句的时候最好加上每个字段的具体类型 |
5)条件语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 如果只想更新或者删除某些固定的记录,那就必须在DML语句后加上一些条件 条件语句的常见格式 where 字段 = 某个值 ; // 不能用两个 = where 字段 is 某个值 ; // is 相当于 = where 字段 != 某个值 ; where 字段 is not 某个值 ; // is not 相当于 != where 字段 > 某个值 ; where 字段1 = 某个值 and 字段2 > 某个值 ; // and相当于C语言中的 && where 字段1 = 某个值 or 字段2 = 某个值 ; // or 相当于C语言中的 || where 字段1 like 某个值 ;表示近似匹配,如 where name like '%a%' ,表示name中只要含有a就匹配 % 一般于like搭配表示包含,近似匹配,多用于模糊查询中 示例: 将t_student表中年龄大于10 并且 姓名不等于jack的记录,年龄都改为 5 update t_student set age = 5 where age > 10 and name != ‘jack’ ; 删除t_student表中年龄小于等于10 或者 年龄大于30的记录 delete from t_student where age <= 10 or age > 30 ; |
6)常用sql语句
1.DDL 数据定义语句
1 2 3 4 5 6 7 8 9 10 11 | 1、创建表 create table 表名(字段名1 类型,字段名2 类型....) create table if not exists 表名 (字段名1 类型,字段名2 类型...) if not exists 表示如果不存在才创建表 示例: 注意事项创建表时必须要有一个主键且是integer类型的格式如下: create table if not exists t_student(id integer primary key autoincrement,name text unique,age integer,height real not null ), 其中primary key表示主键,autoincrement 是自动增长,unique表示是唯一的,not null 不能为空 2、删除表 drop table 表名 drop table if exists 表名 -> if exists 表示存在 |
2.DML 数据操作语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1.插入数据 insert into 表名(字段名1,字段名2...)values(字段名1的值,字段名的值) 示例: insert into t_student (name,age,height)values( 'TheYouth' ,22,1.70) 注意: 属于text类型的(也就是字符型)数据必须用‘’单引号括起来 2.删除数据 delete from t_student 表名 delete from t_student 表名 条件 示例: delete from t_class ,清空t_class所有数据 delete from t_student where name = 'TheYouth' ,删除t_student表中姓名等于TheYouth的数据 3.更新数据(修改数据) update 表名 set 字段名1=字段1的值,字段名2=字段2的值 示例: update t_student set name = 'TheYouth' ,age=29,更新t_student表中所有数据姓名都改为TheYouth,年龄都改为29 update t_student set name = 'Youth' where name = 'TheYouth' |
3.DQL 数据查询语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | 1、查询语句 select * from 表名 select 字段名1,字段名2... from 表名 示例: select name ,age from t_student ,查询t_student表中所有name和age字段 select * from t_student where height > 1.3,查询t_student表中所有height大于1.3的 select * from t_student order by height desc,查询t_student表并按height降序排列,desc是降序,asc是升序,排序默认的是升序 2、起别名 select 字段1 别名 , 字段2 别名 , … from 表名 别名 ; select 字段1 别名, 字段2 as 别名, … from 表名 as 别名 ; select 别名.字段1, 别名.字段2, … from 表名 别名 ; 示例 : select name myname, age myage from t_student ; 给name起个叫做myname的别名,给age起个叫做myage的别名 3、计算总数 select count (字段) from 表名 ; select count ( * ) from 表名 ; 示例 select count (name) from t_student select count(*) from t_student 4、按照某个字段的值,进行排序搜索 select * from t_student order by 字段 ; select * from t_student order by age ; 默认是按照升序排序(由小到大),也可以变为降序(由大到小) select * from t_student order by age desc ; //降序 select * from t_student order by age asc ; // 升序(默认) 也可以用多个字段进行排序 select * from t_student order by age asc, height desc ; 先按照年龄排序(升序),年龄相等就按照身高排序(降序) 5、限制加载数据条数 使用limit可以精确地控制查询结果的数量,比如每次只查询10条数据 格式 select * from 表名 limit 数值1, 数值2 ; 示例 select * from t_student limit 4, 8 ; 可以理解为:跳过最前面4条语句,然后取8条记录 limit常用来做分页查询,比如每页固定显示5条数据,那么应该这样取数据 第1页:limit 0, 5 第2页:limit 5, 5 第3页:limit 10, 5 … 第n页:limit 5*(n-1), 5 6. 模糊查询 select * from 表名 where name like '%查询的字符%' or phone like '%查询的字符% 7、约束 建表时可以给特定的字段设置一些约束条件,常见的约束有 not null :规定字段的值不能为 null unique :规定字段的值必须唯一 default :指定字段的默认值 (建议:尽量给字段设定严格的约束,以保证数据的规范性) 主键约束 如果t_student表中就name和age两个字段,而且有些记录的name和age字段的值都一样时,那么就没法区分这些数据,造成数据库的记录不唯一,这样就不方便管理数据 良好的数据库编程规范应该要保证每条记录的唯一性,为此,增加了主键约束 也就是说,每张表都必须有一个主键,用来标识记录的唯一性 什么是主键 主键(Primary Key,简称PK)用来唯一地标识某一条记录 例如t_student可以增加一个id字段作为主键,相当于人的身份证 主键可以是一个字段或多个字段 主键设计原则 主键应当是对用户没有意义的 永远也不要更新主键 主键不应包含动态变化的数据 主键应当由计算机自动生成 主键的声明 在创表的时候用primary key声明一个主键 create table t_student (id integer primary key, name text, age integer) ; integer类型的id作为t_student表的主键 主键字段 只要声明为primary key,就说明是一个主键字段 主键字段默认就包含了not null 和 unique 两个约束 如果想要让主键自动增长(必须是integer类型),应该增加autoincrement create table t_student (id integer primary key autoincrement, name text, age integer) ; 利用外键约束可以用来建立表与表之间的联系 外键的一般情况是:一张表的某个字段,引用着另一张表的主键字段 新建一个外键 外键名 foreign key (外键字段) references 关联表名(关联表字段) create table t_student (id integer primary key autoincrement, name text, age integer, class_id integer, constraint fk_t_student_class_id_t_class_id foreign key (class_id) references t_class (id); t_student表中有一个叫做fk_t_student_class_id_t_class_id的外键 这个外键的作用是用t_student表中的class_id字段引用t_class表的id字段 什么是表连接查询 需要联合多张表才能查到想要的数据 表连接的类型 内连接:inner join 或者 join (显示的是左右表都有完整字段值的记录) 左外连接:left outer join (保证左表数据的完整性) |
7)数据库增、删、改、查操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | //一.打开数据库,创建表 // 1)创建路径 NSString *cache = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject; NSString *filePath = [cache stringByAppendingPathComponent: @"students.sqlite" ]; // 2)打开数据库 if (sqlite3_open(filePath.UTF8String, &_sqlite3) == SQLITE_OK){ NSLog( @"数据库打开成功" ); } else { NSLog( @"数据库打开失败" ); } NSLog( @"%@" ,filePath); // 3)创建表 char *error = nil; NSString *sql = @"create table if not exists t_students(id integer primary key autoincrement,name text not null unique,age integer no null,height real no null);" ; sqlite3_exec(_sqlite3, sql.UTF8String, NULL, NULL, &error); if (error) { NSLog( @"表创建失败%s" ,error); } else { NSLog( @"表创建成功" ); //二、增 NSString *sql = @"insert into t_students(name,age,height)values('LiJ',29,1.80);" ; char *error = nil; //插入sql语句 sqlite3_exec(_sqlite3, sql.UTF8String, NULL, NULL, &error); if (error) { NSLog( @"接入表数据失败%s" ,error); } else { NSLog( @"接入表数据成功" ); } //注意字符串必须用‘’单引号包起来 for (NSInteger i = 0; i< 20; i++) { NSString *name = [NSString stringWithFormat: @"TheYouth%d" ,arc4random_uniform(100000)]; NSInteger age = [[NSString stringWithFormat: @"%ld" ,i+18] integerValue]; CGFloat height = [[NSString stringWithFormat: @"%.1f" ,0.1+i] floatValue]; NSString *insert = [NSString stringWithFormat: @"insert into t_student (name,age,height)values('%@',%ld,%f)" ,name,age,height]; //执行插入命令 } //三、删 NSString *sql = @"delete from t_students where name = 'xian'" ; char *error = nil; sqlite3_exec(_sqlite3, sql.UTF8String, NULL, NULL, &error); if (error) { NSLog( @"删除表数据失败%s" ,error); } else { NSLog( @"删除表数据成功" ); } //四、改 NSString *sql = @"update t_students set name = 'TheYouth' where name = 'xingZai';" ; char *error = nil; sqlite3_exec(_sqlite3, sql.UTF8String, NULL, NULL, &error); if (error) { NSLog( @"更新表数据失败%s" ,error); } else { NSLog( @"更新表数据成功" ); } //五、查 NSString *sql = @"select * from t_students order by name Asc;" ; //创建句柄 sqlite3_stmt *stmt; if (sqlite3_prepare_v2(_sqlite3, sql.UTF8String, -1, &stmt, NULL) == SQLITE_OK){ //是否准备成功 while (sqlite3_step(stmt) == SQLITE_ROW){ //执行每一行数据 int ID = sqlite3_column_int(stmt, 0); unsigned const char *name = sqlite3_column_text(stmt, 1); int age = sqlite3_column_int(stmt, 2); int height = sqlite3_column_int(stmt, 3); NSLog( @"%d--%s--%d--%d" ,ID,name,age,height); } } 模糊查询 - ( void )searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { NSString *sql = [NSString stringWithFormat: @"select * from t_contact where name like '%%%@%%' or phone like '%%%@%%'" ,searchText,searchText]; //加载查询命令,结果返回到加载数据的数组中 //重新刷新表格 [self.tableView reloadData]; } |
将来的自己,会感谢现在不放弃的自己!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现