FMDB 的使用

作者: henu_Larva | 来源:发表于2018-05-25 10:39 被阅读50次

    FMDB 是对 sqlite 的封装,该文章通过使用 FMDB 对学生数据进行操作,学习记录 FMDB 的使用。
    1.首先,我们需要将 FMDB 再次封装为一个工具类,并提供一些接口供外部调用

    #import <Foundation/Foundation.h>
    @class Student;
    
    @interface FMDBTool : NSObject
    
    /**
     添加一条学生数据
     @param student student
     */
    + (void)insertStudent:(Student *)student;
    
    /**
      添加多条学生数据
     @param students students
     */
    + (void)insertStudents:(NSArray <Student *> *)students;
    
    /**
     更新一条学生数据
     @param student student
     */
    + (void)updateStudent:(Student *)student;
    
    /**
     删除一条学生数据
     @param student student
     */
    + (void)deleteStudent:(Student *)student;
    
    /**
     查询数据
     @return 查询结果
     */
    + (NSArray *)queryStudents;
    
    @end
    

    2.在工具类中实现上述接口

    #import "FMDBTool.h"
    #import "Student.h"
    #import <FMDB.h>
    
    @implementation FMDBTool
    
    //static 保证了 _queue 无法被外部调用
    static FMDatabaseQueue *_queue;
    
    + (void)initialize {
        //获取沙盒路径
        NSString *dbPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"FMDB_Student.sqlite"];
        NSLog(@"dbPath = %@",dbPath);
        //使用此方式可以保证线程安全
        _queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
        
        [_queue inDatabase:^(FMDatabase * _Nonnull db) {
            //创建 t_student 表, 其中 id 为主键,自增长, name 和 age 为需要存储的学生数据字段
            BOOL result = [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer);"];
            if (result) {
                NSLog(@"创建表 t_student 成功");
            } else {
                NSLog(@"创建表 t_student 失败");
            }
        }];
    }
    
    + (void)insertStudent:(Student *)student {
        [_queue inDatabase:^(FMDatabase * _Nonnull db) {
            BOOL result = [db executeUpdate:@"insert into t_student (name, age) values (?, ?);",student.name, @(student.age)];
            if (result) {
                NSLog(@"成功插入一条学生数据 name = %@   age = %d",student.name, student.age);
            } else {
                NSLog(@"插入学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
            }
        }];
    }
    
    + (void)insertStudents:(NSArray<Student *> *)students {
        for (Student *student in students) {
            [self insertStudent:student];
        }
    }
    
    + (void)updateStudent:(Student *)student {
        [_queue inDatabase:^(FMDatabase * _Nonnull db) {
            //更新某个学生的年龄数据
            BOOL result = [db executeUpdate:@"update t_student set age = ? where name = ? ;",@(student.age), student.name];
            if (result) {
                NSLog(@"更新学生数据 name = %@   age = %d  成功",student.name, student.age);
            } else {
                NSLog(@"更新学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
            }
        }];
    }
    
    + (void)deleteStudent:(Student *)student {
        [_queue inDatabase:^(FMDatabase * _Nonnull db) {
            BOOL result = [db executeUpdate:@"delete from t_student where name = ? and age = ? ;",student.name, @(student.age)];
            if (result) {
                NSLog(@"删除学生数据 name = %@   age = %d  成功",student.name, student.age);
            } else {
                NSLog(@"删除学生数据 name = %@   age = %d  失败!!!",student.name, student.age);
            }
        }];
    }
    
    + (NSArray *)queryStudents {
        __block NSMutableArray *students = nil;
        
        //inDatabase 内部是一个同步线程,所以在 block 执行完毕之前,查询方法不会被提前 return
        [_queue inDatabase:^(FMDatabase * _Nonnull db) {
            students = [[NSMutableArray alloc] init];
            //查询年龄大于 20岁的学生数据, ASC为升序(默认), DESC 为降序
            FMResultSet *rs = [db executeQuery:@"select * from t_student where age > ? order by age ASC;",@(20)];
            //用 while
            while (rs.next) {
                NSString *name = [rs stringForColumn:@"name"];
                int age = [rs intForColumn:@"age"];
                
                Student *student = [[Student alloc] init];
                student.name = name;
                student.age = age;
                [students addObject:student];
            }
        }];
        
        return students;
    }
    
    @end
    
    

    3.调用接口,检查是否可以正常使用

    3.1 在控制器内随机生成 30条学生数据,插入到数据库内

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        NSMutableArray *students = [[NSMutableArray alloc] init];
        for (int i = 0; i < 30; i++) {
            //生成随机数据
            NSString *name = [NSString stringWithFormat:@"sdj_%d",arc4random()%50];
            int age = arc4random()%50;
            
            Student *student = [[Student alloc] init];
            student.name = name;
            student.age  = age;
            [students addObject:student];
        }
        [FMDBTool insertStudents:students];
    }
    
    沙盒路径
    控制台日志

    3.2 根据沙盒路径下的文件和日志输出,我们可以认为已经操作成功了。如果需要进一步确认的话,我们可以通过数据库软件打开文件查看数据是否已经插入成功,我这里使用 Navicat 进行查看。


    数据已成功插入

    3.3 数据插入成功后,我们开始对数据进行操作

        //将 sdj_12 的年龄改为 27
        Student *student = [[Student alloc] init];
        student.name = @"sdj_12";
        student.age = 27;
        [FMDBTool updateStudent:student];
    
        //删除 姓名为 sdj_27 且 年龄为 47 的学生数据
        Student *student = [[Student alloc] init];
        student.name = @"sdj_27";
        student.age = 47;
        [FMDBTool deleteStudent:student];
    
        //查询年龄大于 20岁的学生数据
        NSArray *students = [FMDBTool queryStudents];
        for (Student *student in students) {
            NSLog(@"%@  %d",student.name, student.age);
        }
    

    4.以上就是对 FMDB 的简单应用,各位也可以自己查阅 FMDB 的 API,总体使用上是很方便的。

    相关文章

      网友评论

        本文标题:FMDB 的使用

        本文链接:https://www.haomeiwen.com/subject/ntlyjftx.html