持久化存储 --- SQLite3 的基础

一、为什么要使用SQLite3,什么是SQLite3,常见的数据库可以用于移动端嘛?
1、持久化存储的方式有以下几种:
1、plist 只能存储NSDictionary 和NSArray的数据。 2、Preference 偏好设置NSUserDefaults,存取方便,但只能存储小数据。 3、NSCoding (NSKeyedArchiver\NSkeyedUnarchiver)归档可以存储大数据,但是不方便存取,每次存储都会覆盖上一次的内容。 4、SQLite3 重点,存储速度快,而且可以存储大数据且取数据比较方便,可以取出单条数据。 5、Core Data 是对SQLite3的封装。
2、什么是SQLite3,有什么优点?
1) SQLite的优点
SQLite是一款轻型的嵌入式数据库
它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了
它的处理速度比Mysql、PostgreSQL这两款著名的数据库都还快
2)什么是数据库?
数据库(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、可以做本地模糊查询,快速实现用户查询的内容。
2、常用的图形化工具是什么?
Navicat Premium图形化软件是mac系统上数据库操作软件
1)打开SQLite3数据库

2)创建一个新的数据库

3)图形化创建表

4)手动写sql的语句
三、如何使用SQLite3?
1、sql语句
使用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
数据定义语句(DDL:Data Definition Language) 包括create和drop等操作 在数据库中创建新表或删除表(create table或 drop table) 操作注意:只有 crete 和drop 后面需要加上table,然后再跟上表名,其它关键字后面只需要加表名。
2) 数据操作DML
数据操作语句(DML:Data Manipulation Language) 包括insert、update、delete等操作 上面的3种操作分别用于添加、修改、删除表中的数据
3) 数据查询DQL
数据查询语句(DQL:Data Query Language) 可以用于查询获得表中的数据 关键字select是DQL(也是所有SQL)用得最多的操作 其他DQL常用的关键字有where,order by,group by和having
4)sql常用的数据类型,和注意事项
注意:字符型数据必须开单引号包起来如,‘%@’,‘The’ SQLite将数据划分为以下几种存储类型: integer : 整型值 real : 浮点值 text : 文本字符串 blob : 二进制数据(比如文件) 实际上SQLite是无类型的 就算声明为integer类型,还是能存储字符串文本(主键除外) 建表时声明啥类型或者不声明类型都可以,也就意味着创表语句可以这么写: create table t_student(name, age); 为了保持良好的编程规范、方便程序员之间的交流,编写建表语句的时候最好加上每个字段的具体类型
5)条件语句
如果只想更新或者删除某些固定的记录,那就必须在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、创建表
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.插入数据
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、查询语句
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)创建路径
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];
}
将来的自己,会感谢现在不放弃的自己!

浙公网安备 33010602011771号