随意细解:UI -- 数据库

数据库

数据库管理系统

数据库:以⼀定⽅式储存在⼀起,能为多个⽤户共享。具有尽可能⼩得冗余度。与程序彼此独⽴的数据集合。

SQL语句

存储类型:
NULL 值是空值
INTEGER 值是整型
REAL 值是浮点数
TEXT 值是文本字符串
BLOB 值是一个二进制类型

  1. 数据插⼊命令(Insert)
    insert into lanOuStudent 表名

    @"insert into Student(number,name,gender,age,imageData) values(?,?,?,?,?)"
  2. 数据更新命令(Update)
    update Student 表名 where 根据条件更新 set age 更新的字段

    update Student set age = '%ld' where name = '%@'
  3. 数据删除命令(Delete)
    delete from Student 表名 where 根据条件删除

    delete from Student where age > '%ld'
  4. 数据检索命令(Select)
    where 根据条件查询 多条件用 and 连接 *表示 查询所有字段

    select * from lanOuStudent where name = ? and age = ?
    
    select * from lanOuStudent 查询所有

iOS的数据库技术的实现

重要函数参数:

  • sqlite3_exec
    包含两个步骤 1.准备 2.执行语句

    sqlite3_exec(sqlite3 *, const char *sql, int (*callback)(void *, int, char **, char **), void *, char **errmsg)

    第1个参数 是前面open函数得到的指针。
    第2个参数 是一条sql语句。
    第3个参数 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。
    第4个参数 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。
    第5个参数 是错误信息。

  • 准备语句

    sqlite3_prepare_v2(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **ppStmt, const char **pzTail)

    int nByte 可设为 -1 指sql语句长度 可以无限长
    sqlite3_stmt 跟随指针 地址
    const char **pzTail 截取sql语句未使用部分

  • 执行准备的绑定语句

    sqlite3_step()
  • 绑定查询值

    sqlite3_bind_text(stmt, 1, name.UTF8String, -1, NULL);

    第二个参数 指查询的第几个问号 从1开始

  • 读取数据

    char *name = (char *)sqlite3_column_text(stmt, 1);
    
    NSData *data = [NSData dataWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)];

错误码

#define SQLITE_OK           0   /* 成功 | Successful result */
    /* 错误码开始 */
    #define SQLITE_ERROR        1   /* SQL错误 或 丢失数据库 | SQL error or missing database */
    #define SQLITE_INTERNAL     2   /* SQLite 内部逻辑错误 | Internal logic error in SQLite */
    #define SQLITE_PERM         3   /* 拒绝访问 | Access permission denied */
    #define SQLITE_ABORT        4   /* 回调函数请求取消操作 | Callback routine requested an abort */
    #define SQLITE_BUSY         5   /* 数据库文件被锁定 | The database file is locked */
    #define SQLITE_LOCKED       6   /* 数据库中的一个表被锁定 | A table in the database is locked */
    #define SQLITE_NOMEM        7   /* 某次 malloc() 函数调用失败 | A malloc() failed */
    #define SQLITE_READONLY     8   /* 尝试写入一个只读数据库 | Attempt to write a readonly database */
    #define SQLITE_INTERRUPT    9   /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */
    #define SQLITE_IOERR       10   /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */
    #define SQLITE_CORRUPT     11   /* 数据库磁盘映像不正确 | The database disk image is malformed */
    #define SQLITE_NOTFOUND    12   /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */
    #define SQLITE_FULL        13   /* 因为数据库满导致插入失败 | Insertion failed because database is full */
    #define SQLITE_CANTOPEN    14   /* 无法打开数据库文件 | Unable to open the database file */
    #define SQLITE_PROTOCOL    15   /* 数据库锁定协议错误 | Database lock protocol error */
    #define SQLITE_EMPTY       16   /* 数据库为空 | Database is empty */
    #define SQLITE_SCHEMA      17   /* 数据结构发生改变 | The database schema changed */
    #define SQLITE_TOOBIG      18   /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */
    #define SQLITE_CONSTRAINT  19   /* 由于约束违例而取消 | Abort due to constraint violation */
    #define SQLITE_MISMATCH    20   /* 数据类型不匹配 | Data type mismatch */
    #define SQLITE_MISUSE      21   /* 不正确的库使用 | Library used incorrectly */
    #define SQLITE_NOLFS       22   /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */
    #define SQLITE_AUTH        23   /* 授权失败 | Authorization denied */
    #define SQLITE_FORMAT      24   /* 附加数据库格式错误 | Auxiliary database format error */
    #define SQLITE_RANGE       25   /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */
    #define SQLITE_NOTADB      26   /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */
    #define SQLITE_ROW         100  /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */
    #define SQLITE_DONE        101  /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing */
    /* 错误码结束 */

SQLite嵌⼊式数据库

  • 使用SQLite数据库步骤:
    1.引入框架
    2.在数据库操作类里 引入

// 单例的初始化方法
 + (SQLiteManager *)shareManager
{
    // 定义一个静态区指针
    static SQLiteManager *manager = nil;
    if (manager == nil) {
        manager = [[SQLiteManager alloc]init];
    }
    // 调用创建表的方法
    [manager createTable];

    return manager;
}
  • 静态区定义一个指针
static sqlite3 *db = nil;
  • 打开数据库
 - (sqlite3 *)openDB
{
    // 判断数据库 是否存在 如果存在的话 直接返回
    if (db != nil) {
        return db;
    }
    // 不存在 则创建一个并打开
    // 获取路径
    NSString *DocumentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    // 拼接数据库文件路径(拼接的数据库文件的名字)
    NSString *dbPath = [DocumentPath stringByAppendingPathComponent:@"/Student.sqlite"];
    NSLog(@"%@", dbPath);

    // 创建或者打开数据库
    // 参数1:文件的路径 (需要把OC的字符串转化成C语言的) dbPath.UTF8String
    // 参数2:数据库的地址
    // 接收一下返回 判断是否打开成功
    int result = sqlite3_open(dbPath.UTF8String, &db);
    // SQLITE_OK 可以查表得到错误
    if (result == SQLITE_OK) {
        NSLog(@"打开成功");
    }else{
        NSLog(@"打开失败");
    }
    return db;
}
  • 关闭数据库
 - (void)closeDB
{
   int result = sqlite3_close(db);
    // 判断是否关闭成功
    if (result == SQLITE_OK) {
        NSLog(@"关闭成功");
        // 把数据库的指针重置为空
        db = nil;

    }else{
        NSLog(@"关闭失败");
    }

}
  • 创建一张表
 - (void)createTable
{
    // 注意:一定要在操作时先打开数据库,操作完毕关闭数据库

    // 打开数据库
    db = [self openDB];

    // 写sql语句
    NSString *sql = @"create table if not exists Students( number integer primary key not null, name text not null, age integer not null, gender text not null, imageData blob not null)";
    // 执行sql语句
    // 准备与执行语句的操作


   int result = sqlite3_exec(db, sql.UTF8String , NULL, NULL, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"建表成功");
    }else{
        NSLog(@"建表失败");
    }

    // 关闭数据库
    [self closeDB];

}
  • 插入数据
- (void)insertTableWithStudent:(StudentModel *)stu
{
    // 打开数据库
    db = [self openDB];
    // 写sql语句
    NSString *sql = @"insert into Students (number, name, age, gender, imageData) values (?,?,?,?,?)";
    // 创建一个跟随指针(指令集)
    sqlite3_stmt *stmt = nil;
    // 执行sql语句
    // 预执行函数,需要用跟随指针,绑定问号,然后一步一步执行
    // 判断sql语句是否正确
    int result = sqlite3_prepare(db, sql.UTF8String, - 1, &stmt, NULL);
    if (result == SQLITE_OK) {

        // 绑定问号(根据sql语句决定绑定的顺序)
        // 注意:绑定的顺序从 1 开始
        // 参数2 :绑定的顺序
        // 参数3 :要插入的值
        sqlite3_bind_int(stmt, 1, (int)stu.number);
        sqlite3_bind_text(stmt, 2, stu.name.UTF8String, - 1, NULL);
        sqlite3_bind_int(stmt, 3, (int)stu.age);
        sqlite3_bind_text(stmt, 4, stu.gender.UTF8String, - 1, NULL);
        // 绑定二进制数据
        // [stu.imageData bytes] 相当于获取到data数据的内容
        // (int)[stu.imageData length] 相当于获取到data数据的长度
        sqlite3_bind_blob(stmt, 5, [stu.imageData bytes], (int)[stu.imageData length], NULL);

        // 执行绑定的语句
        sqlite3_step(stmt);

         NSLog(@"插入成功");
    }else{
        NSLog(@"插入失败");
    }

    // 不管插入是否成功 都要释放跟随指针
    sqlite3_finalize(stmt);

    // 关闭数据库
    [self closeDB];

}
  • 删除数据
- (void)deleteTableWithAge:(NSInteger)age
{


#pragma mark ---- 不绑定删除 需要拼接sql语句
    // 打开数据库
 //   db = [self openDB];
    // 写sql语句
//    NSString *sql = [NSString stringWithFormat:@"delete from Students where age > '%ld'", age];
//    // 执行sql语句
//   int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
//    // 判断一下执行结果
//    if (result == SQLITE_OK) {
//        NSLog(@"删除成功");
//    }else{
//        NSLog(@"删除失败");
//    }
//    // 关闭数据库
//    [self closeDB];

#pragma mark ---- 绑定删除 

    // 打开数据库
    db = [self openDB];
    // 写sql语句
    NSString *sql = @"delete from Students where age > ? ";
    // 创建跟随指针
    sqlite3_stmt *stmt = nil;

   int result = sqlite3_prepare(db, sql.UTF8String, - 1, &stmt, NULL);
    if (result == SQLITE_OK) {
        // 绑定问号
        sqlite3_bind_int(stmt, 1, (int)age);
        // 执行跟随指针绑定的语句
        sqlite3_step(stmt);
        NSLog(@"删除成功");
    }else{
        NSLog(@"删除失败");
    }
    // 释放跟随指针
    sqlite3_finalize(stmt);
    // 关闭数据库
    [self closeDB];
}
  • 更新数据
 - (void)updateAge:(NSInteger)age withName:(NSString *)name
{
    db = [self openDB];

    NSString *sql = [NSString stringWithFormat:@"update Students set age = '%ld' where name = '%@'", age, name];
    // 执行sql语句
   int result = sqlite3_exec(db, sql.UTF8String, NULL, NULL, NULL);
    if (result == SQLITE_OK) {
        NSLog(@"更新成功");
    }else{
        NSLog(@"更新失败");
    }

    [self closeDB];
}
  • 查询数据(根据条件查询)
- (StudentModel *)selectStudentWith:(NSString *)name age:(NSInteger)age
{
    db = [self openDB];

    NSString *sql = @"select * from Students where name = ? and age = ?";

    sqlite3_stmt *stem = nil;
    // 创建一个对象
    StudentModel *model = [[StudentModel alloc]init];
    // 预执行
   int result = sqlite3_prepare(db, sql.UTF8String, - 1, &stem, NULL);

    if (result == SQLITE_OK) {
        sqlite3_bind_text(stem, 1, name.UTF8String, (int)name.length, NULL);
        sqlite3_bind_int(stem, 2, (int)age);

        // 查询时, 如果下一行准备好了 返回 SQLITE_ROW
        // 这时可以继续查询
        while (sqlite3_step(stem) == SQLITE_ROW) {
            // 读取数据
            // int iCol 列数
            // 如果查询所有的字段的话 那么这个列数就根据你创建表的顺序一样
            // 注意:从0开始

            // 如果你查询的是特定的字段,那么这个列数就要根据你的sql语句来写
            // 也是 从0 开始
            int number = sqlite3_column_int(stem, 0);
            char *name = (char *)sqlite3_column_text(stem, 1);
            int age = sqlite3_column_int(stem, 2);
            char *gender = (char *)sqlite3_column_text(stem, 3);
            // 读取二进制数据
            NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(stem, 4) length:sqlite3_column_bytes(stem, 4)];

            // 赋值model
            // [NSString stringWithUTF8String:(const char *)] 把C语言字符串转化成OC字符串
            model.name = [NSString stringWithUTF8String:name];
            model.number = number;
            model.age = age;
            model.gender = [NSString stringWithUTF8String:gender];
            model.imageData = imageData;

        }

        NSLog(@"查询成功");
    }else{
        NSLog(@"查询失败");
    }

    // 释放跟随指针
    sqlite3_finalize(stem);
    // 关闭数据库
    [self closeDB];

    return [model autorelease];
}
  • 查询所有Student(返回一个数组)
- (NSArray *)selectAllStudents
{
    // 打开数据库
    db = [self openDB];
    NSString *sql = @"select * from Students";
    // 创建一个可变数组
    NSMutableArray *array = [NSMutableArray array];
    // 创建跟随指针
    sqlite3_stmt *stmt = nil;
    // 预执行
    int result = sqlite3_prepare(db, sql.UTF8String, - 1, &stmt, NULL);
    if (result == SQLITE_OK) {

        while (sqlite3_step(stmt) == SQLITE_ROW) {
            // 读取数据
            int number = sqlite3_column_int(stmt, 0);
            char *name = (char *)sqlite3_column_text(stmt, 1);
            int age = sqlite3_column_int(stmt, 2);
            char *gender = (char *)sqlite3_column_text(stmt, 3);
            NSData *imageData = [NSData dataWithBytes:sqlite3_column_blob(stmt, 4) length:sqlite3_column_bytes(stmt, 4)];
            // 赋值model
            StudentModel *model = [[StudentModel alloc]init];
            model.number = number;
            model.name = [NSString stringWithUTF8String:name];
            model.age = age;
            model.gender = [NSString stringWithUTF8String:gender];
            model.imageData = imageData;
            // 添加到数组
            [array addObject:model];
            [model release];
        }

        NSLog(@"查询成功");
    }else{
        NSLog(@"查询失败");
    }

    sqlite3_finalize(stmt);

    [self closeDB];

    return array;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { namespace 'com.example.qrtopicture' compileSdk 33 defaultConfig { applicationId "com.example.qrtopicture" minSdk 24 targetSdk 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { compose true } composeOptions { kotlinCompilerExtensionVersion '1.3.2' } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } } dependencies { implementation 'com.google.zxing:core:3.4.1' implementation 'com.google.zxing:android-core:3.3.0' implementation 'com.google.zxing:android-integration:3.3.0' implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'androidx.core:core-ktx:1.8.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' implementation 'androidx.activity:activity-compose:1.5.1' implementation platform('androidx.compose:compose-bom:2022.10.00') implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.material3:material3' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' }帮我看看
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值