宽容他人,放过自己。

数据库简单实用

Posted on By anchoriteFili

常见的数据库


  • 1.SQL
  • 2.My SQL
  • 3.Oracle

数据库:以一定方式储存在一起,能为多个用户共享,具有尽可能小的冗余度,与程序彼此独立的数据集合。

SQL是关系型数据库,使用数据表管理和存储数据

SQL命令


1.数据插入命令(Insert)
insert into products (pro_id,pro_name,pro_price,pro_date) values (1,'wahaha',1,'2015-1-1')

insert into….values….——关键字
products ——————–表名
pro_id,pro_name———–表中字段名称
‘wahaha’——————要插入的数据

2.数据更新命令(Update)
update products set pro_name = 'coffee' where  pro_id = 1

update……set……where..—–关键字
products————————表名
pro_name = ‘coffee’———–字段名和要更新的内容
pro_id = 1———————-更新检索条件

3.数据删除命令(Delete)

全部删除

delete from products  

根据检索删除

delete from products where pro_id = 1;

delete from…..where…..——–关键字
products ————————-表名
pro_id = 1 ———————–要删除的检索条件

4.数据查询命令(Select)
select * from products where pro_id = 1

select from…….where.. ———关键字
porducts ————————–表名
pro_id = 1 ————————查询条件

5.在数据库中创建表
create table book (name text,content text)

book —————————–表名
name text ———————–表元素名与元素格式

6.删除整张表
drop table [book]

book —————————-表名

7.根据表名查表名
select tbl_name from sqlite_master where type ='table' and name = 'book1'

book1 ————————–表名

8.增加表字段
alter table 表名 add column 字段名 字段类型
alter table t_student add column age integer;
9.删除表字段
alter table 表名 drop column 字段名
10.修改表字段
alter table 表名 rename column 旧字段名 to 新字段名

添加Frameworks

091955528166018.png

创建用于打开和关闭数据库的类DB

#import <Foundation/Foundation.h>
#import <sqlite3.h> // 轻量级的数据库,简化版

@interface DB : NSObject

//创建打开和关闭数据库的类DB,并创建打开和关闭数据库的两个类方法
+ (sqlite3 *)openDB;
+ (void)closeDB;

@end

#import "DB.h"

@implementation DB

//创建静态区全局变量,创建一个空的数据库
static sqlite3 *db = nil;

//打开数据库方法中,先将SQLiteManager创建的数据库拷贝到Document文件夹中
+ (sqlite3 *)openDB {
    
//    将products.sqlite数据库文件从数据包中拷贝到沙盒中
//    获取源地址--获取数据库在bundle中的路径
    NSString *sourcePath = [[NSBundle mainBundle] pathForResource:@"Products" ofType:@"sqlite"];
//    获取目的路径地址
    NSString *destPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingString:@"/Products.sqlite"];
//    创建NSFileManager类对象
    NSFileManager *manager = [NSFileManager defaultManager];
//    判断文件是否已经存在于沙盒中,如果存在就不在拷贝
    BOOL isContain = [manager fileExistsAtPath:destPath];
    if (!isContain) {
        [manager copyItemAtPath:sourcePath toPath:destPath error:nil];
    }
//    如果数据库已经打开,就不用再次打开,直接返回db
    if (db) {
        return db;
    }
//    使用数据库打开命令打开数据库,result表示是否打开成功,&db直接指向打开的数据库
    int result = sqlite3_open(destPath.UTF8String, &db);
    if (result == SQLITE_OK) {
        NSLog(@"打开成果");
    }else {
        NSLog(@"打开失败");
    }
    return db;
}

+ (void)closeDB {
    
//    执行数据库关闭命令
    int result = sqlite3_close(db);
    if (result == SQLITE_OK) {
        NSLog(@"关闭成功");
    }else {
        NSLog(@"关闭失败");
    }
}

@end

创建对数据库的管理类DBManager
先创建Product类,用于个类之间数据库内各字段的传递

#import <Foundation/Foundation.h>

//创建各类之间传递字段的类
@interface Product : NSObject

@property (nonatomic,assign) int proId;
@property (nonatomic,copy) NSString *proName;
@property (nonatomic,assign) float proPrice;
@property (nonatomic,copy) NSString *proDate;
@property (nonatomic,copy) NSString *proAd;

@end

#import "Product.h"

@implementation Product

- (void)dealloc {
    [_proName release];
    [_proDate release];
    [_proAd release];
    [super dealloc];
}

@end

创建对数据库的管理类,用于插入(Insert)、删除(Delete)、修改(Update)、查询(Select)

数据库样式

092051574887577.png

#import <Foundation/Foundation.h>
#import "Product.h"
#import <sqlite3.h>
#import "DB.h"

@interface DBManager : NSObject
//创建数据库管理类
//插入商品 返回值根据需要自己设定
- (BOOL)insertProduct:(Product *)pro;

//删除商品
- (BOOL)deleteProductById:(int)proId;
- (BOOL)deleteAllProducts;

//修改商品
- (void)updateProduct:(Product *)pro byId:(int)proId;

//查询指定商品
- (Product *)selectProductById:(int)proId;

//查询所有商品
- (NSArray *)selectAllProducts;

@end

#import "DBManager.h"

@implementation DBManager

//插入商品 返回值根据需要自己设定
- (BOOL)insertProduct:(Product *)pro {
    
//    1.打开数据库
    sqlite3 *db = [DB openDB];
//    2.准备sql语句
    NSString *sql = [NSString stringWithFormat:@"insert into products values (%d,'%@',%f,'%@','%@')",pro.proId,pro.proName,pro.proPrice,pro.proDate,pro.proAd];
//    3.执行sql语句
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
//    4.关闭数据库,要写在if上面,return将会结束一切返回
    [DB closeDB];
    if (result == SQLITE_OK) {
        NSLog(@"成功");
        return YES;
    }else {
        NSLog(@"失败:%d",result);
        return NO;
    }
}

//删除商品
- (BOOL)deleteProductById:(int)proId {
    
//    1.打开数据库
    sqlite3 *db = [DB openDB];
//    2.准备sql语句
    NSString *sql =[NSString stringWithFormat:@"delete from products where pro = %d",proId];
//    3.执行sql sqlite3_exec 只有传输和接收得作用
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    [DB closeDB];
    
    if (result == SQLITE_OK) {
        NSLog(@"成功");
        return YES;
    }else {
        return NO;
    }
}
- (BOOL)deleteAllProducts {
    
    sqlite3 *db = [DB openDB];
    NSString *sql = @"delete from products";
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    [DB closeDB];
    if (result == SQLITE_OK) {
        NSLog(@"全部删除");
        return YES;
    }else {
        NSLog(@"全部删除失败");
        return NO;
    }
    
    return NO;
}

//修改商品
- (void)updateProduct:(Product *)pro byId:(int)proId {
}

/*
 语句对象的生命周期:
 1.使用sqlite3_prepare_v2或相关的函数创建这个对象
 2.使用sqlite3_bind_*()给宿主参数绑定值
 3.通过调用sqlite3_step一次或多次来执行这个sql
 4.使用sqlite3_reset()重置这个语句,然后回到第2步,这个过程做0次或多次
 5.使用sqlite3_finalize()销毁这个对象
 */


//查询指定商品
- (Product *)selectProductById:(int)proId {
    
//    1.打开数据库
    sqlite3 *db = [DB openDB];
//    2.准备sql语句
    NSString *sql = @"select * from products where pro_id = ?";
//    3.创建指向编译好的sql准备语句的指针
//    能够使用sqlite3_step()执行的编译好的准备语句的指针,如果错误发生,它被置为NULL,如:输入的文本不包括sql语句。编译好的sql语句完成使用后,使用sqlite3_finalize()删除它。
    sqlite3_stmt *stmt = nil;
//    4.将数据库指针sql,文本sql和sql的跟随指针整合,为下边的执行做准备
//    将sql文本转换成一个准备语句对象,同时返回这个对象的指针。这个接口需要一个数据连接指针db以及一个要准备的包含SQL语句的文本sql,它实际并不执行(evaluate)这个SQL语句,它仅仅为执行准备这个sql语句
//    推荐在任何的程序中都使用sqlite3_prepare_v2这个函数,sqlite3_prepare只是用于前向兼容
    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);
//    5.如果准备过程成功,则返回SQLITE_OK,否则返回错误代码,
    if (result == SQLITE_OK) {
//        给参数绑定值,stmt指向sql准备语句,1表示的是spl语句中第一个?参数,第三个proId表示用于替换?处的参数
        
        /*
         宿主参数(host parameters)
         在传给sqlite3_prepare_v2()的sqld的语句文本或者他的变量中,满足如下模板的文字将被替换成一个参数:
         1.?
         2.?NNN,NNN代表数字
         3.:VVV,VVV代表字符
         4.@VVV
         5.$VVV
         上面的这些模板中,NNN代表一个数字,VVV代表一个字符数字标记符(例如:222表示名称为222的标记符),sql语句中的参数(变量)通过上面的几个模板来指定,如:
         "sleect ? from ?"这个语句中指定了两个参数,sqlite语句中的第一个参数的索引值是1,这就知道这个语句之呢过的两个参数的索引分别为1和2,使用"?"的话黑背自动给予索引值,而使用"?NNN"则可以自己指定参数的索引值为NNN。":VVV"表示一个名为"VVV"的参数,它也有一个索引值,被自动指定。
         而sqlite3_bind*()是用来给这些参数赋值的 sqlite3_bind_text(stmt,1,name.UTF8String,-1,nil)
         */
        
        sqlite3_bind_int(stmt, 1, proId);
        
//       6.sqlite3_step(stmt)这相当于一个遍历器,根据sql中的命令,一行一行的对数据库中的数据进行遍历,遍历出得数据可以通过sqlite3_column取出
        /*
         这个过程用于执行由前面sqlite3_prepare创建的准备语句。这个语句执行到结果的第一行可用的位置。继续前进到结果的第二行的话,只需再次调用sqlite3_step(),继续调用sqlite3_step(),直到这个语句完成,那些不反悔结果的语句(如:INSERT,UPTDATE,或DELETE),sqlite3_step()只执行一次就返回
         返回值:函数的返回值基于创建sqlite3_stmt参数所使用的函数,假如是使用老版本的接口sqlite3_prpare()和sqlite3_prepare16(),返回值会是SQLITE_BUSY,SQLITE_DONE,SQLITE_ROW,SQLITE_ERROR或SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()则会同时返回这些结果码和扩展结果码。
         */
        int stepResult = sqlite3_step(stmt);
        if (stepResult == SQLITE_ROW) {
            Product *pro = [[Product alloc] init];
//            7.利用sqlite3_column*()取出某一行的某一列的值
            /*
             sqlite3_column()
             这个过程从执行sqlite3_step()执行一个准备语句得到的结果集的当前行中返回一个列。每次sqlite3_step得到一个结果集的列停下后,这个过程就可以被多次调用区查询这个行的各列的值。对列操作是由多个函数,均以sqlite3_column为前缀
             参数:第一个为准备语句对象的指针stmt,第二个参数是这一行中想要返回的列的索引。最左边的一列的索引号是0,行的列数可以使用sqlite3_column_count()获得
             */
            pro.proId = sqlite3_column_int(stmt, 0);
            const char *name = (const char *)sqlite3_column_text(stmt, 1);
            pro.proName = [NSString stringWithUTF8String:name];
            pro.proPrice = sqlite3_column_double(stmt, 2);
            const char *date = (const char *)sqlite3_column_text(stmt, 3);
            pro.proDate = [NSString stringWithUTF8String:date];
            const char *ad = (const char *)sqlite3_column_text(stmt, 4);
            pro.proAd = [NSString stringWithUTF8String:ad];
            
            sqlite3_finalize(stmt);
            return [pro autorelease];
            
        } else {
            sqlite3_finalize(stmt);
        }
    }
    return nil;
}

//查询所有商品
- (NSArray *)selectAllProducts {
    
//    1.打开数据库
    sqlite3 *db = [DB openDB];
//    2.创建sql语句
    NSString *sql = @"select * from products";
//    3.创建准备语句指针
    sqlite3_stmt *stmt = nil;
//    4.创建准备语句
    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);
//    5.如果准备完毕
    if (result == SQLITE_OK) {
        NSMutableArray *proArr = [[NSMutableArray alloc] init];
        while (sqlite3_step(stmt) == SQLITE_ROW) {
            @autoreleasepool {
                Product *pro = [[Product alloc] init];
                pro.proId = sqlite3_column_int(stmt, 0);
                const char *name = (const char *)sqlite3_column_text(stmt, 1);
                pro.proName = [NSString stringWithUTF8String:name];
                pro.proPrice = sqlite3_column_double(stmt, 2);
                const char *date = (const char *)sqlite3_column_text(stmt, 3);
                pro.proDate = [NSString stringWithUTF8String:date];
                const char *ad = (const char *)sqlite3_column_text(stmt, 4);
                pro.proAd = [NSString stringWithUTF8String:ad];
                [proArr addObject:pro];
                [pro release];
                
            }
            sqlite3_finalize(stmt);
            return proArr;
        }
        
    } else {
            sqlite3_finalize(stmt);
        }
    
    return nil;
}


@end

小说数据库代码

#import <Foundation/Foundation.h>
#import <sqlite3.h>
#import "DB.h"
#import "Book.h"

@interface DBManager : NSObject

#pragma mark 插入书本
- (BOOL)insertBook:(Book *)book;
#pragma mark 根据书名删除书
- (BOOL)deleteBookByBook:(NSString *)book;
#pragma mark 根据章节名更新章节内容
- (void)updateContent:(NSString *)content byBookName:(NSString *)bookName;
#pragma mark 根据章节名查找内容
- (NSString *)selectContentByBookName:(NSString *)bookName;

@end

#import "DBManager.h"

@implementation DBManager

#pragma mark 插入书本
- (BOOL)insertBook:(Book *)book {
    
    //    1.打开数据库
    sqlite3 *db = [DB openDB];
    //    2.准备sql语句
    NSString *sql = [NSString stringWithFormat:@"insert into books values ('%@','%@','%@')",book.book,book.name,book.content];
    //    3.执行sql语句
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    //    4.关闭数据库,要写在if上面,return将会结束一切返回
    [DB closeDB];
    if (result == SQLITE_OK) {
        NSLog(@"成功");
        return YES;
    }else {
        NSLog(@"失败:%d",result);
        return NO;
    }
}

#pragma mark 根据书名删除书
- (BOOL)deleteBookByBook:(NSString *)book {
    
    //    1.打开数据库
    sqlite3 *db = [DB openDB];
    //    2.准备sql语句
    NSString *sql =[NSString stringWithFormat:@"delete from books where book = '%@'",book];
    //    3.执行sql sqlite3_exec 只有传输和接收得作用
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    [DB closeDB];
    
    if (result == SQLITE_OK) {
        NSLog(@"成功");
        return YES;
    }else {
        return NO;
    }
    return NO;
}

#pragma mark 根据章节名更新章节内容
- (void)updateContent:(NSString *)content byBookName:(NSString *)bookName {
    
    //    1.打开数据库
    sqlite3 *db = [DB openDB];
    //    2.准备sql语句
    NSString *sql =[NSString stringWithFormat:@"update books set content = '%@' where name = '%@'",content,bookName];
    //    3.执行sql sqlite3_exec 只有传输和接收得作用
    int result = sqlite3_exec(db, sql.UTF8String, nil, nil, nil);
    [DB closeDB];
    
    if (result == SQLITE_OK) {
        NSLog(@"更新成功");
    }else {
        NSLog(@"更新失败");
    }
}

#pragma mark 根据章节名查找内容
- (NSString *)selectContentByBookName:(NSString *)bookName {
    
    //    1.打开数据库
    sqlite3 *db = [DB openDB];
//    直接添加,不用再用sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*))进行替换
//    直接用内容content代替*,可以实现单个查找,用*实现一行查找

    NSString *sql = [NSString stringWithFormat:@"select content from books where name = '%@'",bookName];
    sqlite3_stmt *stmt = nil;
    int result = sqlite3_prepare_v2(db, sql.UTF8String, -1, &stmt, nil);
    if (result == SQLITE_OK) {
        
        int stepResult = sqlite3_step(stmt);
        if (stepResult == SQLITE_ROW) {
            
            const char *contentC = (const char *)sqlite3_column_text(stmt, 0);
            NSString *content = [NSString stringWithUTF8String:contentC];
            sqlite3_finalize(stmt);
            [DB closeDB];
            return content;
        } else {
            sqlite3_finalize(stmt);
            NSLog(@"hehehe");
            return nil;
        }
    }
    return nil;
}

@end