/* Database.sqlite存放在*.app中的, 存放在*app中的文件是隻讀的, 不能修改, 所以若要做增刪改查, 需要將Database.sqlite存放到除了*app之外的其他文件夾下(比如:Document)
Database類負責對數據庫的打開和關閉
對sqlite操作需要添加靜態庫
*/
#import <Foundation/Foundation.h>
@interface Database : NSObject
<span style="background-color: rgb(153, 153, 255);">//打開數據庫
+ (sqlite3 *)openDB;
//關閉數據庫
+ (void)closeDB;</span>
@end<pre name="code" class="objc">#define FILE_NAME @"Database.sqlite"
<span style="background-color: rgb(102, 51, 255);">#import "Database.h"</span>
<span style="background-color: rgb(102, 102, 204);">static sqlite3 *db = nil;//指向數據庫的指針
@implementation Database</span>
//打開數據庫
+ (sqlite3 *)openDB
{
if (!db) {
//1 獲取document文件夾的路徑
//參數1: 文件夾的名字 參數2: 查找域 參數3: 是否使用絕對路徑
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
//獲取數據庫文件的路徑
NSString *dbPath = [docPath stringByAppendingPathComponent:FILE_NAME];
//iOS 中管理文件的類, 負責複製文件, 刪除文件, 移動文件
NSFileManager *fm = [NSFileManager defaultManager];//管理數據庫
//判斷document中是否有sqlite文件
if (![fm fileExistsAtPath:dbPath]) {
//獲取在*.app中sqlite文件的路徑
NSString *boundlePath = [[NSBundle mainBundle] pathForResource:@"Database" ofType:@"sqlite"];
NSError *error = nil;
//將*.app中sqlite文件複製一份到dbPath(會複製不成功)
BOOL result = [fm copyItemAtPath:boundlePath toPath:dbPath error:&error];//複製一份到Document文件夾內
//若複製文件失敗, 打印錯誤信息
if (!result) {
NSLog(@"%@", error);
}
}
//打開數據庫 參數1: 文件路徑(UTF8String可以將OC的NSString轉爲C中的char) 參數2: 接受數據庫的指針
sqlite3_open([dbPath UTF8String], &db);
}
return db;
}
//關閉數據庫
+ (void)closeDB
{
sqlite3_close(db);
db = nil;
}
@end
軟件中的符號:
1.常見的由:A M D R ? C (?一般是添加操作,軟件沒有識別,需要手動添加)
2.黑底白字:代表你修改的文件數,並且還沒有上傳
白底黑字:服務器上的修改的文件數,並且沒有更新
*/
<span style="background-color: rgb(102, 102, 204);">@implementation CLViewController</span>
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//數據庫(Database): 存放數據的倉庫, 存放的是一張的表, 特別像Excel, Numbers, 都以表格的形式存放數據, 可以創建多張表
//常見的數據庫: sqllite, MySQL, SQLServer, Oracle, Access
//爲什麼要用數據庫 1 文件讀寫和歸檔讀取數據需要一次把數據全部讀出來, 佔用內存開銷大 2 數據庫數據效率高, 體現在增刪改查
//SQL Structured Query Language 用於對數據庫的操作語句 (增刪改查)
//SQL 語句不區分大小寫, 字符串需要加""或''
//主鍵: 是一條數據的唯一標識符, 一張表只能有一個主鍵, 主鍵不能夠重複, 一般把主鍵名設爲"id", 不需要賦值, 會自增
//*代表所有的字段
//where是條件
//創建表: creat table 表名 (字段名 字段數據類型 是否爲主鍵, 字段名 字段數據類型, 字段名 字段數據類型...)
//查: select 字段名 (或者*) from 表名 where 字段名 = 值
//增: insert into 表名 (字段1, 字段2...) values (值1, 值2...)
//改: update 表名 set 字段 = 值 where 字段 = 值
//刪: delete from 表名 where 字段 = 值
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)selectAll:(id)sender {
NSMutableArray *array = [DatabaseHelper getAllStudents];
for (Student *stu in array) {
NSLog(@"%@", stu);
}
}
- (IBAction)selectOne:(id)sender {
Student *stu = [DatabaseHelper getStudentWithID:2];
NSLog(@"%@", stu);
}
- (IBAction)insetOne:(id)sender {
Student *stu = [[Student alloc] init];
stu.name = @"vaercly";
stu.sex = @"man";
stu.age = 22;
BOOL result = [DatabaseHelper insertStudent:stu];
NSLog(@"%d", result);
}
- (IBAction)updateName:(id)sender {
[DatabaseHelper updateStudentName:@"崔成傑" byID:5];
}
- (IBAction)deleteOne:(id)sender {
[DatabaseHelper deleteStudentWithID:5];
}
@end
#import <Foundation/Foundation.h>
@class Student;
<span style="background-color: rgb(51, 204, 255);">@interface DatabaseHelper : NSObject</span>
//查詢所有學生
+ (NSMutableArray *)getAllStudents;
//查詢單個學生
+ (Student *)getStudentWithID:(NSInteger)aID;
//添加一個新學生
+ (BOOL)insertStudent:(Student *)aStudent;
//修改學生的姓名
+ (BOOL)updateStudentName:(NSString *)aName byID:(NSInteger)aID;
//刪除一個學生
+ (BOOL)deleteStudentWithID:(NSInteger)aID;
@end<pre name="code" class="objc">@implementation DatabaseHelper
//查詢所有學生
+ (NSMutableArray *)getAllStudents
{
//打開數據庫
sqlite3 *db = [Database openDB];
//數據庫操作指針 stmt:statement
sqlite3_stmt *stmt = nil;
//驗證SQL的正確性 參數1: 數據庫指針, 參數2: SQL語句, 參數3: SQL語句的長度 -1代表無限長(會自動匹配長度), 參數4: 返回數據庫操作指針, 參數5: 爲未來做準備的, 預留參數, 一般寫成NULL
int result = sqlite3_prepare_v2(db, "select * from Student", -1, &stmt, NULL);
NSMutableArray *studentArr = [NSMutableArray array];
//判斷SQL執行的結果
if (result == SQLITE_OK) {
while (sqlite3_step(stmt) == SQLITE_ROW) {//存在一行數據
//列數從0開始
int ID = sqlite3_column_int(stmt, 0);
const unsigned char *name = sqlite3_column_text(stmt, 1);
const unsigned char *sex = sqlite3_column_text(stmt, 2);
int age = sqlite3_column_int(stmt, 3);
//blob類型(二進制格式)的獲取
//1 獲取長度
int length = sqlite3_column_bytes(stmt, 4);
//2 獲取數據
const void *photo = sqlite3_column_blob(stmt, 4);
//3 轉成NSData
NSData *photoData = [NSData dataWithBytes:photo length:length];
//4 轉成UIImage
UIImage *image = [UIImage imageWithData:photoData];
//封裝Student模型
Student *student = [[Student alloc] init];
student.ID = ID;
//把c語言中的name轉化爲oc中的對象
student.name = [NSString stringWithUTF8String:(const char *)name];
student.sex = [NSString stringWithUTF8String:(const char *)sex];
student.age = age;
student.photo = image;
//添加到數組
[studentArr addObject:student];
[student release];
}
}
//釋放stmt指針
sqlite3_finalize(stmt);
//關閉數據庫
[Database closeDB];
return studentArr;
}
//查詢單個學生
+ (Student *)getStudentWithID:(NSInteger)aID
{
sqlite3 *db = [Database openDB];
sqlite3_stmt *stmt = nil;
NSString *sqlStr = [NSString stringWithFormat:@"select * from Student where id = %d", aID];
int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
//創建學生對象,接收
Student *student = nil;
if (result == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
int ID = sqlite3_column_int(stmt, 0);
const unsigned char *name = sqlite3_column_text(stmt, 1);
const unsigned char *sex = sqlite3_column_text(stmt, 2);
int age = sqlite3_column_int(stmt, 3);
//返回二進制的長度
int length = sqlite3_column_bytes(stmt, 4);
const unsigned char *photo = sqlite3_column_blob(stmt, 4);
NSData *photoData = [NSData dataWithBytes:photo length:length];
UIImage *image = [UIImage imageWithData:photoData];
student = [[Student alloc] init];
student.ID = ID;
student.name = [NSString stringWithUTF8String:(const char *)name];
student.sex = [NSString stringWithUTF8String:(const char *)sex];
student.age = age;
student.photo = image;
}
}
sqlite3_finalize(stmt);
[Database closeDB];
return student;
}
//添加一個新學生
+ (BOOL)insertStudent:(Student *)aStudent
{
sqlite3 *db = [Database openDB];
sqlite3_stmt *stmt = nil;
NSString *sqlStr = [NSString stringWithFormat:@"insert into Student (name, sex, age) values ('%@', '%@', '%d')", aStudent.name, aStudent.sex, aStudent.age];
int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
//判斷語句執行完成沒有
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
[Database closeDB];
return YES;
}
}
sqlite3_finalize(stmt);
[Database closeDB];
return NO;
}
//修改學生的姓名
+ (BOOL)updateStudentName:(NSString *)aName byID:(NSInteger)aID
{
sqlite3 *db = [Database openDB];
sqlite3_stmt *stmt = nil;
NSString *sqlStr = [NSString stringWithFormat:@"update Student set name = '%@' where id = %d", aName, aID];
int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
if (result == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {//覺的應加一個判斷, 若有這一行則修改 //存在一行數據
//判斷是否執行完畢
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
[Database closeDB];
return YES;
}
}
}
sqlite3_finalize(stmt);
[Database closeDB];
return NO;
}
//刪除一個學生
+ (BOOL)deleteStudentWithID:(NSInteger)aID
{
sqlite3 *db = [Database openDB];
sqlite3_stmt *stmt = nil;
NSString *sqlStr = [NSString stringWithFormat:@"delete from Student where id = %d", aID];
//驗證sqi正確性
int result = sqlite3_prepare_v2(db, [sqlStr UTF8String], -1, &stmt, NULL);
//判斷執行的結果
if (result == SQLITE_OK) {
if (sqlite3_step(stmt) == SQLITE_ROW) {//覺的應加一個判斷, 若有這一行則刪除
if (sqlite3_step(stmt) == SQLITE_DONE) {
sqlite3_finalize(stmt);
[Database closeDB];
return YES;
}
}
}
sqlite3_finalize(stmt);
[Database closeDB];
return NO;
}
@end