常见的数据库
- 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
创建用于打开和关闭数据库的类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)
数据库样式
#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