# 知识点
 1).SQLite数据库简介
 2).SQL语句
 3).FMDB的使用
 
 
==================================
1.数据库
 1).按照数据结构来组织、存储和管理数据的仓库
 
 2).数据库的作用
 存储数据
 组织和管理数据
 
 3).关系型数据库
 用二维表格来表⽰复杂的数据关系
 
 4).SQLite数据库,MySQL,SQLServer,Orcle
 轻量级的关系型数据库
 设计之初就是针对嵌⼊式做的
 iOS和Android都是⽤的SQLite
 
 5).SQLite支持的数据类型
 NULL - 空值
 INTERGER - 有符号整数类型
 REAL - 浮点数类型
 TEXT - 字符串(其编码取决于DB的编码) 
 BLOB - 二进制表⽰示
 
 
 
 
==================================
2.SQL语句,结构化查询语言(Structured Query Language),专⻔用作数据库操作的语言,官⽅推荐关键字⼤写
```
 1).建表语句
 create table if not exists TableName(Field1 DataType, Field2 Data, ...)
    NSString *sql = @"CREATE TABLE IF NOT EXISTS T_Student(AutoId INTEGER PRIMARY KEY AUTOINCREMENT, sid TEXT NOT NULL, name TEXT, age INTEGER)";
         if ([self.database executeUpdate:sql]) {
        NSLog(@"建表成功了");}
            else {
        NSLog(@"建表失败");
    }
 2).插入语句
 insert into TableName(Field1, Field2, ...) values(value1, value2, ...)
         NSString *sql = @"INSERT INTO T_Student(sid, name, age) VALUES(?, ?, 20)";
 
    if ([self.database executeUpdate:sql, sidStr, @"LiSi"]) {
        NSLog(@"插入数据成功");
    }
    else {
        NSLog(@"插入数据失败");
    }
 
 3).更新数据
 update TableName set Field1=Value1, Field2=Value2
            // 更新(修改)的SQL
 = 'LiSi'";
    
    if ([self.database executeUpdate:sql]) {
        NSLog(@"更新成功");
    }
    else {
        NSLog(@"更新失败");
    }
 
 4).删除数据
 delete from TableName
    NSString *sql = @"DELETE FROM T_Student WHERE sid='4321'";
 
 5).查询语句
    
    
 <1>查询表格中所有字段的数据
 select * from user
 
//* 通配符,代表要所有列的字段
 
 <2>查询指定的字段
 获取所有用户名
 select username from user
 select username,password from user
 
 <3>根据指定的条件进行查询   
 sid为1410001人的信息获取出来
 select * from user where sid='1410001'
 
                  //where 后跟的是条件语句,= > <   like
 
 <4>根据多个条件进行查询
 判断用户名为lisi,密码为123456的用户是否存在?
 select * from user where username='lisi' and password='123456'
 
 <5>查询后需要排序-----淘宝查询按照价格排序,desc表示降序,默认升序
 select * from user order by sid desc
 
 <6>获取数据行数
 select count(*) from user
                //从user表中查找从索引2开始的数两个的记录 
 select * from  user limit 2 ,2
                查找 age=10的所有记录   按照 passwd 升序 排列
 select * from user  where age=10  order by passwd asc
 
 查找 age 分别 是 2   3   5 的所有记录
 select * from user where age in (2,3,5)
 
 查找 age  在2<=age <= 5 区间的所有记录 
 select * from user where age between  2 and 5
 
 模糊找到 找到 username 中包含 xiaohong字符串的所有记录
 select * from user where username like '%xiaohong%'
 
 查找 指定范围的记录     limit 1,2  表示 从索引 1开始 数两条记录
 //索引 值 数字 是从0开始表示
 select * from user  limit 1,2
                
                
                
 select Field from TableName // 查询指定字段数据
 
 select * from TableName limit 10 // 查询所有数据并且取最后10条数据
 
 select * from TableName order by Field asc // 查询结果根据哪个字段来排排序(asc升序/desc降序)
 select count (*) from TableName // 查询数据的数量
        
        
     // 查询的SQL
    // SELECT * FROM T_Student 查询所有
    // SELECT name FROM T_Student WHERE age >= 100 查询大于100岁的人的名字
    NSString *sql = @"SELECT * FROM T_Student";
    
    // 执行查询语句,返回的是一个表示结果集的FMResultSet对象
    FMResultSet *rs = [self.database executeQuery:sql];
    
    // 遍历结果集,FMResultSet用一个指针来指向查到的每一条记录(每一行数据)
    while ([rs next]) {
        // stringForColumn,从当前指向的这一行数据,取出对应字段的值,并且,把值转成NSString对象
        NSString *sidStr = [rs stringForColumn:@"sid"];
        NSString *name = [rs stringForColumn:@"name"];
        NSInteger age = [rs intForColumn:@"age"];
        NSInteger AutoId = [rs intForColumn:@"AutoId"];
 
        NSLog(@"%@, %@, %d %d", sidStr, name, age,AutoId);
    }
 
 6).条件判断
 select * from TableName where Field=Value   // 等于
 where Field>Value   // 大于
 where Field<Value   // 小于
 where Field<>Value // 不等于
 
 where Field in ('Value1', 'Value2', 'Value3') // 在集合中的⼀个
 where Field between Value1 and Value2  // 在两个值之间
 
```
 
==================================
3.FMDB,SQLite数据库原⽣的接口是C语言的,iOS开发中,几乎都是⽤FMDB来管理SQLite数据库
 
FMDB开源库 操作 sqlite 的一个第三库
增删改查
 
使用库:
(1)导入文件, 直接拖进来
(2)添加系统库  libsqlite3.dylib
(3)添加头文件
#import "FMDatabase.h"
fmdb  有 arc 和非arc 的代码 
如果是非arc 的代码在arc 环境下编译 要 混编 -fno-objc-arc
 1).创建数据库(已经存在就不创建了)
 + databaseWithPath:
 
 2).打开关闭数据库
 - open
 - close
 
 3).执行SQL语句
 - executeUpdate  // 非查询的SQL,都是用这个执行
   // 查询的SQL
 
 4).查询结果集,FMResultRet
 遍历
 - next // 执⾏行⼀一次,指针就会移动到下⼀一条记录
 
 当前记录操作
 // 根据字段名,取出值,并转成String
 // 根据字段下标,取出值,并转成String
 
 
 
 
# CoreData
# 知识点
 理解CoreData
    能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句。
    
 在SQLite和模型之间做了 层映射关系
 在SQLite和模型之间做了 层映射关系 当我们对模型做了 些操作的时候,会映射到数据表中
 
===============================
 
1.NSManagedObjectModel,  来加载CoreData数据模型文件,所有的数据模型可以 全部加载到此对象中  (代表CoreData模型文件)
 ```
 // 从应用程序包中加载模型文件
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
```
 
2.NSPersistentStoreCoordinator, 数据 持久化存储协调器,负责调 度上层与底层对数据的操作。(添加持久化存储库)
```
// 传入模型对象,初始化NSPersistentStoreCoordinator
    NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
        // 构建SQLite数据库文件的路径
    NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.sqlite"]];
    // 添加持久化存储库,这里使用SQLite作为存储库
    NSError *error = nil;
    NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
    if (store == nil) { // 直接抛异常
        [NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]];
    }else {
        NSLog(@"添加数据库成功");
    }
```
 
3.NSManagedObjectContext, 用于操作数据 模型(对象),并监测数据模型(对象)的变化(负责应用于数据库之间的交互)
```
    // 初始化上下文,设置persistentStoreCoordinator属性
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    context.persistentStoreCoordinator = psc;
```
 
4.NSManagedObject, 具体的数据模型对象,通过Core Data从数据库取出的对象,默认情况下都是NSManagedObject对象
NSManagedObject的工作模式有点类似于NSDictionary对象,通过键-值对来存取所有的实体属性
1> setValue:forKey:存储属性值(属性名为key)
2> valueForKey:获取属性值(属性名为key)
 
 
NSEntityDescription,模型描述类,能够实例化得到具体的数据模型对象(来描述实体)
 
NSFetchRequest,数据查询请求类
 
NSPredicate,通过谓词设置查询条件的类
 
```
    // 初始化一个查询请求
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    // 设置要查询的实体
    request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:_context];
    // 设置排序(按照age降序)
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
    request.sortDescriptors = [NSArray arrayWithObject:sort];
    // 设置条件过滤(搜索name中包含字符串"Itcast-1"的记录,注意:设置条件过滤时,数据库SQL语句中的%要用*来代替,所以%Itcast-1%应该写成*Itcast-1*)
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*xiao*"];
    request.predicate = predicate;
    // 执行请求
    NSError *error = nil;
    NSArray *objs = [_context executeFetchRequest:request error:&error];
    if (error) {
        [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
    }
    // 遍历数据
    for (NSManagedObject *obj in objs) {
        NSLog(@"name=%@",[obj valueForKey:@"name"]);
        NSLog(@"age=%@",[obj valueForKey:@"age"]);
 
    }
```
 
 
 
 
===============================
NSManagedObjectContext
•
操作数据
- save: // 保存更改到数据库
- deleteObject: // 删除 个实体对象(一行记录)
- executeFetchRequest: // 执行查询
 
===============================
 
 
NSEntityDescription
在指定的Context和Entity中插个实例对象(一条数据)
- insertNewObjectForEntityForName:inManagedObjectContext:
 
===============================
 
NSFetchRequest
 成查询请求
- fetchRequestWithEntityName:
 
===============================
•
NSPredicate
•
NSPredicate
 成条件
+ predicateWithFormat:
Format , %K表 要查询的属性, %@来表 要传 的值
```
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*xiao*"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"*xiao*"]];
    [NSPredicate predicateWithFormat:@"name = %@", @"*xiao*"]
```
===============================
 
开发步骤总结:
1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息
2.初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)
3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD操作
4.然后进行数据 添加删除操作
 
# MagicalRecord
 
MagicalRecord
需要引 头 件
import "MagicalRecord.h"
需要在AppDelegate中的 初始化
•
didFinishLaunchingWithOptions函数中
+ setupCoreDataStackWithStoreAtURL: + setupCoreDataStackWithStoreNamed:
需要在程序终 的时候,清空
•
MagicalRecord
+ cleanUp
 
 
 
NSManagedObjectContext的Category + MR_defaultContext: // 取得通 的Context
- MR_saveToPersistentStoreAndWait // 保存Context到数据库中(同步)
- MR_saveToPersistentStoreWithCompletion: // 保存Context到数据库(异步)
 
 
 
•
MagicalRecord NSManagedObject(我们的模型)的Category
+ MR_findAll // 查询这个类的所有实体(所有数据)
+ MR_findAllWithPredicate: // 根据条件查询
+ MR_createEntity // 创建 个实体对象(  数据)
- MR_deleteEntity // 从数据库中删除 个实体(  数据)