美文网首页iOS
iOS FMDB框架 数据库使用

iOS FMDB框架 数据库使用

作者: dragonYao | 来源:发表于2017-02-20 18:27 被阅读71次

    之前项目中使用的是CoraData,发现每次的更新数据库中新的属性会非常的麻烦,这里正好尝试着使用一下 FMDB。写了一个FMDB基本用法(增加、删除、查询)的Demo,修改的代码后续会加上。先贴上github连接地址 Demo地址 ,OSChina连接地址 OSChina连接

    看一下实现效果
    1111.gif
    注意点
    • 这篇文章适合初次使用FDMB者,已经掌握了FMDB使用方法的,就不需要看了。
    • 在做增删改查的时候 VALUES都是对象,Demo中我为了使用的方便都用了String类型
    • 在FMDB这个开源库中,使用到的增、删、改都是更新的动作
    • 为了方便操作写一个管理类,主要用来管理数据库创建,数据表的创建查询,这里以学生管理为例。上代码:
    先来看一下管理类的.m文件
    #import <Foundation/Foundation.h>
    @class Student;
    @interface StudentManager : NSObject
    
    //因为在很多地方都需要用到,在这里我使用单利设计
    + (StudentManager *)shareManager;
    //创建数据库
    - (void)createDatabase;
    //添加学生,传入的是学生对象
    - (void)insertStudent:(Student *)student;
    //添加学生,这里传入的是学生的ID
    - (void)addStudentWithStudentId:(NSString *)studentId;
    //通过学生的ID删除某一个学生
    - (void)deleteStudentWithStudentId:(NSString *)studentId;
    //根据某个ID查询该学生是否存在
    - (NSArray *)findStudentWithId:(NSString *)studentId;
    //这个主要是添加学生的时候,判断这个学生是否已经存在
    - (BOOL)isStudentExist:(NSString *)studentId;
    //查询所有的学生,并返回
    - (NSMutableArray *)findAllStudents;
    // 删除所有的学生
    - (void)clearAllStudents;
    @end
    
    • 既然是管理,那就要所有关于数据库的操作在这一个类中完成
    下面看一下具体的实现.m文件
    #import "StudentManager.h"
    #import "Student.h"
    #import "FMDB.h"
    
    static NSString *const kStudentDB = @"Students.sqlite";
    static NSString *const kStudentTable = @"student";
    
    @interface StudentManager ()
    
    @property (nonatomic, copy) NSString *dbPathName;
    @property (nonatomic, strong) FMDatabase *database;
    
    @end
    
    @implementation StudentManager
    
    + (StudentManager *)shareManager {
        static StudentManager *shareManager = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            shareManager = [[StudentManager alloc] init];
        });
        return shareManager;
    }
    
    - (instancetype)init {
        self = [super init];
        if (self) {
            NSInteger status = [self initStudentDBWithDBName:kStudentDB];
            if (status == -1) {
                //失败
                NSLog(@"database name 为空");
            }
            else {
                //创建数据库 或者 已经存在
            }
        }
        return self;
    }
    
    //初始化数据库
    - (NSInteger)initStudentDBWithDBName:(NSString *)dbName {
        if (!dbName) {
            NSLog(@"数据库名称为空");
            return -1;//初始化数据库失败
        }
        //将数据库保存在沙盒路径下
        NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];;
        self.dbPathName = [documentPath stringByAppendingFormat:@"/%@", dbName];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isExist = [fileManager fileExistsAtPath:self.dbPathName];
        if (!isExist) {
            NSLog(@"need create database");
            [self connectDB];
            return 0;//不存在需要创建
        }
        else {
            NSLog(@"database is exist");
            return 1;//已经存在
        }
    }
    
    //连接数据库
    - (void)connectDB {
        if (!_database) {
            //创建
            _database = [[FMDatabase alloc] initWithPath:self.dbPathName];
        }
        if (![_database open]) {
            NSLog(@"打开数据库失败");
        }
        else {
        }
    }
    
    //关闭数据库
    - (void)closeDB {
        BOOL isClose = [_database close];
        if (isClose) {
            NSLog(@"关闭成功");
        }
    }
    
    //创建数据库
    - (void)createDatabase {
        //查找数据库所有的表 并且表的名称为 kStudentDB的数据库
        NSString *query = [NSString stringWithFormat:@"select count(*) from sqlite_master where type = 'table' and name = %@", kStudentTable];
        FMResultSet *resultSet = [self.database executeQuery:query];
        [resultSet next];
        NSInteger count = [resultSet intForColumnIndex:0];
        //对count进行bool转化
        BOOL existTable = !!count;
        if (existTable) {
            //数据表已经存在 是否更新数据库
            NSLog(@"数据库已经存在");
        } else {
            //插入新的数据库 @"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL);"
            NSString *sqlString = @"CREATE TABLE IF NOT EXISTS student (id integer PRIMARY KEY AUTOINCREMENT NOT NULL, student_id text NOT NULL, stu_name VARCHAR(20), stu_score VARCHAR(20))";
            BOOL result = [self.database executeUpdate:sqlString];
            if (!result) {
                NSLog(@"数据表创建失败");
            }
            else {
                NSLog(@"数据表创建成功");
            }
        }
    }
    
    //删除某个学生
    - (void)deleteStudentWithStudentId:(NSString *)studentId {
        [self.database open];
        NSString *sqlQuery = [NSString stringWithFormat:@"DELETE FROM student WHERE student_id=%@", studentId];
        BOOL result = [self.database executeUpdate:sqlQuery];
        if (result) {
            NSLog(@"从数据库删除学生成功!");
        }
        [self.database close];
    }
    
    //插入某个学生
    - (void)insertStudent:(Student *)student {
        [self.database open];
        NSMutableString *sqlQuery = [NSMutableString stringWithFormat:@"INSERT INTO student (student_id, stu_name, stu_score) VALUES(?,?,?)"];
        NSString *stuId = [NSString stringWithFormat:@"%@", student.studentId];
        NSLog(@"student = %@ %@ %@", student.name, stuId, student.score);
        BOOL result = [self.database executeUpdate:sqlQuery withArgumentsInArray:@[stuId,student.name, student.score]];
    //    BOOL result = [self.database executeUpdate:sqlQuery, student.studentId, student.name, student.score];
        if (result) {
            NSLog(@"inser student succeed!");
            [self.database close];
        }
        else {
            NSLog(@"inser student failure!");
            [self.database close];
        }
    }
    
    //添加某个学生Id
    - (void)addStudentWithStudentId:(NSString *)studentId {
        [self.database open];
        NSMutableString *query = [NSMutableString stringWithFormat:@"INSERT INTO student"];
        NSMutableString *keys = [NSMutableString stringWithFormat:@" ("];
        NSMutableString *values = [NSMutableString stringWithFormat:@" ( "];
        NSMutableArray *arrguments = [NSMutableArray array];
        if (studentId) {
            [keys appendString:@"student_id,"];
            [values appendString:@"?,"];
            [arrguments addObject:studentId];
        }
        [keys appendString:@")"];
        [values appendString:@")"];
        [query appendFormat:@" %@ VALUES %@", [keys stringByReplacingOccurrencesOfString:@",)" withString:@")"], [values stringByReplacingOccurrencesOfString:@",)" withString:@")"]];
        NSLog(@"query = %@", query);
        [self.database executeUpdate:query withArgumentsInArray:arrguments];
        [self.database close];
    }
    
    //清空全部数据
    - (void)clearAllStudents {
        [self.database open];
        NSString *query = @"DELETE FROM student";
        BOOL result = [self.database executeUpdate:query];
        if (result) {
            NSLog(@"删除所有学生成功");
        }
        else {
             NSLog(@"删除所有学生失败");
        }
        [self.database close];
    }
    
    //查询所有的学生
    - (NSMutableArray *)findAllStudents {
        [self.database open];
        NSString *sqlString = @"SELECT student_id, stu_name, stu_score FROM student";
        FMResultSet *resultSet = [self.database executeQuery:sqlString];
        NSMutableArray *array = [NSMutableArray array];
        while ([resultSet next]) {
            Student *stu = [Student new];
            stu.studentId = [resultSet stringForColumn:@"student_id"];
            stu.name = [resultSet stringForColumn:@"stu_name"];
            stu.score = [resultSet stringForColumn:@"stu_score"];
            [array addObject:stu];
        }
        [resultSet close];
        [self.database close];
        return array;
    }
    
    //查询某一个学生
    - (NSArray *)findStudentWithId:(NSString *)studentId {
        [self.database open];
        NSString *sqlQuery = [NSString stringWithFormat:@"SELECT student_id FROM student WHERE student_id = %@", studentId];
        FMResultSet *resultSet = [self.database executeQuery:sqlQuery];
        NSMutableArray *array = [NSMutableArray array];
        while ([resultSet next]) {
            Student *stu = [Student new];
            stu.studentId = [resultSet stringForColumn:@"student_id"];
            [array addObject:stu];
        }
        [resultSet close];
        [self.database close];
        return array;
    }
    
    //判断这个学生是否已经存在
    - (BOOL)isStudentExist:(NSString *)studentId {
        [self.database open];
        if ([self findStudentWithId:studentId].count > 0) {
            [self.database close];
            return YES;
        } else {
            [self.database close];
            return NO;
        }
    }
    
    
    定义好了管理的类,下面就要开始使用了
    • 管理的类已经定义好了,使用起来就非常的简单了,一行代码实现增删该查,废话不多说,上代码
    #import "StudentListController.h"
    #import "Student.h"
    #import "StudentManager.h"
    #import "StudentInfoCell.h"
    
    typedef NS_ENUM(NSInteger, AlertTextFieldTag) {
        AlertTextFieldStudentNameTag = 10,
        AlertTextFieldStudentIdTag,
        AlertTextFieldStudentScoreTag
    };
    
    static NSString *const kStudentInfoCell = @"StudentInfoCell";
    
    @interface StudentListController () {
        Student *addStu;//添加的学生
    }
    
    @property (nonatomic, strong) NSMutableArray *students;
    @property (nonatomic, assign) AlertTextFieldTag textFieldTag;
    
    @end
    
    @implementation StudentListController
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"FMDBTestDemo";
        UIBarButtonItem *backItem = [[UIBarButtonItem alloc]
                            initWithImage:[[UIImage imageNamed:@"back_navigation"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
                                    style:UIBarButtonItemStylePlain
                                   target:self
                                   action:@selector(back:)];
        self.navigationItem.leftBarButtonItem = backItem;
        UIBarButtonItem *insertItem = [[UIBarButtonItem alloc]
                                     initWithImage:[[UIImage imageNamed:@"mine_profile"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
                                     style:UIBarButtonItemStylePlain
                                     target:self
                                     action:@selector(insertAStudent:)];
        self.navigationItem.rightBarButtonItem = insertItem;
        //获取所有的学生
        self.students = [[StudentManager shareManager] findAllStudents];
        //register cell
        [self.tableView registerNib:[UINib nibWithNibName:kStudentInfoCell bundle:nil] forCellReuseIdentifier:kStudentInfoCell];
        //初始化添加学生的全局变量
        addStu = [Student new];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    
        return 1;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return self.students.count;
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        StudentInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:kStudentInfoCell];
        Student *student = (Student *)self.students[indexPath.row];
        [cell configCellWithStudent:student];
    
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            // Delete the row from the data source
    //        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        } else if (editingStyle == UITableViewCellEditingStyleInsert) {
    
        }   
    }
    
    #pragma mark - Table view delegate
    
    - (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        __weak typeof(self) weakSelf = self;
        UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"删除" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            NSLog(@"删除数据");
            [weakSelf.students removeObjectAtIndex:indexPath.row];
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            Student *student = (Student *)weakSelf.students[indexPath.row];
            [[StudentManager shareManager] deleteStudentWithStudentId:student.studentId];
        }];
        deleteAction.backgroundColor = [UIColor redColor];
    
        UITableViewRowAction *addAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDefault title:@"标记" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
            [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"标记成功");
        }];
        addAction.backgroundColor = [UIColor orangeColor];
        return @[addAction, deleteAction];
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return 80.0;
    }
    
    #pragma mark - Button Action
    
    - (void)insertAStudent:(id)sender {
        __weak typeof(self) weakSelf = self;
        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"手动录入" message:@"请输入学生姓名、学号、考试分数" preferredStyle:UIAlertControllerStyleAlert];
        [alertVC addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.placeholder = @"学生姓名";
            textField.tag = AlertTextFieldStudentNameTag;
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidchanged:) name:UITextFieldTextDidChangeNotification object:textField];
        }];
        [alertVC addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.placeholder = @"学生学号";
            textField.tag = AlertTextFieldStudentIdTag;
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidchanged:) name:UITextFieldTextDidChangeNotification object:textField];
        }];
        [alertVC addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.placeholder = @"学生成绩";
            textField.tag = AlertTextFieldStudentScoreTag;
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidchanged:) name:UITextFieldTextDidChangeNotification object:textField];
        }];
        //取消
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
        }];
        [alertVC addAction:cancelAction];
        //确定
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [[StudentManager shareManager] insertStudent:addStu];
            [self.students addObject:addStu];
            [weakSelf.tableView reloadData];
            [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
        }];
        confirmAction.enabled = NO;
        [alertVC addAction:confirmAction];
        [self presentViewController:alertVC animated:YES completion:nil];
    }
    
    - (void)back:(id)sender {
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    #pragma mark - Notification 
    - (void)textDidchanged:(NSNotification *)notification {
        UITextField *textField = (UITextField *)notification.object;
        NSInteger textFieldTag = textField.tag;
        UIAlertController *alertVC = (UIAlertController *)self.presentedViewController;//拿到弹出的Alertcontroller
        if (alertVC) {
            if (textFieldTag == AlertTextFieldStudentNameTag) {
                UITextField *stuNameTextField = [alertVC.textFields objectAtIndex:0];
                if (stuNameTextField.text.length > 0) {
                    addStu.name = stuNameTextField.text;
                }
                else {
                    NSLog(@"学生名称为空");
                }
            } else if (textFieldTag == AlertTextFieldStudentIdTag) {
                UITextField *stuIdTextField = [alertVC.textFields objectAtIndex:1];
                if (stuIdTextField.text.length > 0) {
                    addStu.studentId = stuIdTextField.text;
                }
                else {
                    NSLog(@"学生名称为空");
                }
            } else if (textFieldTag == AlertTextFieldStudentScoreTag) {
                UITextField *stuScoreTextField = [alertVC.textFields objectAtIndex:2];
                if (stuScoreTextField.text.length > 0) {
                    addStu.score = stuScoreTextField.text;
                }
            }
            else {
                NSLog(@"无效的tag");
            }
            if (addStu.name.length > 0
                && addStu.studentId.length > 0 && addStu.score.length > 0) {
                UIAlertAction *confirmAction = alertVC.actions.lastObject;
                confirmAction.enabled = YES;
            }
        }
    }
    
    
    FMDB库的基本使用到这里就结束了。如有使用不正确的地方,请指正🙏。再次附上Demo代码

    相关文章

      网友评论

        本文标题:iOS FMDB框架 数据库使用

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