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

一、为什么要使用SQLite3,什么是SQLite3,常见的数据库可以用于移动端嘛?

1、持久化存储的方式有以下几种:

1、plist   只能存储NSDictionary 和NSArray的数据。
2、Preference 偏好设置NSUserDefaults,存取方便,但只能存储小数据。
3、NSCoding (NSKeyedArchiverNSkeyedUnarchiver)归档可以存储大数据,但是不方便存取,每次存储都会覆盖上一次的内容。
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];
}
将来的自己,会感谢现在不放弃的自己!
原文地址:https://www.cnblogs.com/TheYouth/p/6647475.html