iOS數據庫應用一:SQLite


 

 

 

保存數據的方式很多,plist files, XML, 或者 文本文件,但是效率不高。SQLite提供了在大數據中高效查詢、檢索的本地存儲功能。

SQLite is an open source library, written in C, that implements a self-contained SQL relational database engine. You can use SQLite to store large amounts of relational data. The developers of SQLite have optimized it for use on embedded devices like the iPhone and iPad.

Although the Core Data application programming interface (API) is also designed to store data on iOS, its primary purpose is to persist objects created by your application. SQLite excels when pre- loading your application with a large amount of data, whereas Core Data excels at managing data created on the device.

 

一、建立數據庫:
1、command-line

 

1、sqlite3 catalog.db//建立數據庫

2、//建表
CREATE TABLE "main"."Product"
("ID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,
"Name" TEXT, "ManufacturerID" INTEGER, "Details" TEXT, "Price" DOUBLE, "QuantityOnHand" INTEGER, "CountryOfOriginID" INTEGER, "Image" TEXT );

CREATE TABLE "main"."Manufacturer"
("ManufacturerID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "Name" TEXT NOT NULL );

CREATE TABLE "main"."Country"
("CountryID" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , "Country" TEXT NOT NULL );

2、使用火狐瀏覽器的SQLite Manager 插件

下載地址:

http://code.google.com/p/sqlite-manager

二,插入數據:

2、插入一行數據:

INSERT INTO "main"."Product" ("Name","ManufacturerID","Details","Price","QuantityOnHand", "CountryOfOriginID","Image")
VALUES ('Widget A','1','Details of Widget A','1.29','5','1', 'Canvas_1');

3、從文件中導入數據到數據庫:

.separator "\t"

.import "products.txt" Product

命令: .import
sqlite> .import 文件名 表名
注1: 不要忘了開頭的點
注2: 這條語句不能用分號結束. 非SQL不需要分號結束.
注3: 需要查看默認的分隔符separator. 必須一致. 如果不一致可能導致sqlite字段分割錯誤.
        查看分隔符使用命令  .show , 如果不一致可直接修改, 比如:
        sqlite>.separator ","
        將分隔符轉為逗號.

4、導出:

實現方式: 將輸出重定向至文件.
命令: .output
sqlite> .output a.txt
然后輸入sql語句, 查詢出要導的數據. 查詢后,數據不會顯示在屏幕上,而直接寫入文件.
結束后,輸入
sqlite> .output stdout
將輸出重定向至屏幕.
舉例: 
將 tab_xx 中的數據導出到文件a.txt
sqlite> .output a.txt
sqlite> select * from tab_xx;

在屏幕顯示:

sqlite> .output stdout

sqlite> select * from tab_xx;

 三、在iOS軟件中使用SQLite:
1、首先要對數據建模

2、抽象出操作數據庫的API,以便以后更換數據庫。

#import <Foundation/Foundation.h>

// This includes the header for the SQLite library.
#import <sqlite3.h>
#import "Product.h"

@interface DBAccess : NSObject {
    
    
}

- (NSMutableArray*) getAllProducts;
- (void) closeDatabase;
- (void)initializeDatabase;

@end
#import "DBAccess.h"

@implementation DBAccess

// Reference to the SQLite database.
sqlite3* database;

-(id) init
{
    //  Call super init to invoke superclass initiation code
    if ((self = [super init]))
    {
        //  set the reference to the database
        [self initializeDatabase];
    }
    return self;
}

// Open the database connection
- (void)initializeDatabase {
    
    // Get the database from the application bundle.
    NSString *path = [[NSBundle mainBundle]
                      pathForResource:@"catalog"
                      ofType:@"db"];
    
    // Open the database.
    if (sqlite3_open([path UTF8String], &database) == SQLITE_OK)
    {
        NSLog(@"Opening Database");
    }
    else
    {
        // Call close to properly clean up
        sqlite3_close(database);
        NSAssert1(0, @"Failed to open database: ‘%s’.",
                  sqlite3_errmsg(database));
    }
}


-(void) closeDatabase
{
    // Close the database.
    if (sqlite3_close(database) != SQLITE_OK) {
        NSAssert1(0, @"Error: failed to close database: ‘%s’.",
                  sqlite3_errmsg(database));
    }
}

- (NSMutableArray*) getAllProducts
{
    //  The array of products that we will create
    NSMutableArray *products = [[NSMutableArray alloc] init];

    //  The SQL statement that we plan on executing against the database
    const char *sql = "SELECT product.ID,product.Name, \
    Manufacturer.name,product.details,product.price,\
    product.quantityonhand, country.country, \
    product.image FROM Product,Manufacturer, \
    Country where manufacturer.manufacturerid=product.manufacturerid \
    and product.countryoforiginid=country.countryid";

    //  The SQLite statement object that will hold our result set
    sqlite3_stmt *statement;
    
    // Prepare the statement to compile the SQL query into byte-code
    int sqlResult = sqlite3_prepare_v2(database, sql, -1, &statement, NULL);

    if ( sqlResult== SQLITE_OK) {
        // Step through the results - once for each row.
        while (sqlite3_step(statement) == SQLITE_ROW) {
            //  allocate a Product object to add to products array
            Product  *product = [[Product alloc] init];
            // The second parameter is the column index (0 based) in
            // the result set.
            char *name = (char *)sqlite3_column_text(statement, 1);
            char *manufacturer = (char *)sqlite3_column_text(statement, 2);
            char *details = (char *)sqlite3_column_text(statement, 3);
            char *countryOfOrigin = (char *)sqlite3_column_text(statement, 6);
            char *image = (char *)sqlite3_column_text(statement, 7);
            
            //  Set all the attributes of the product
            //product是數據模型的對象
            product.ID = sqlite3_column_int(statement, 0);
            product.name = (name) ? [NSString stringWithUTF8String:name] : @"";
            product.manufacturer = (manufacturer) ? [NSString
                                                     stringWithUTF8String:manufacturer] : @"";
            product.details = (details) ? [NSString stringWithUTF8String:details] : @"";
            product.price = sqlite3_column_double(statement, 4);
            product.quantity = sqlite3_column_int(statement, 5);
            product.countryOfOrigin = (countryOfOrigin) ? [NSString
                                                           stringWithUTF8String:countryOfOrigin] : @"";
            product.image = (image) ? [NSString stringWithUTF8String:image] : @"";
            
            // Add the product to the products array
            [products addObject:product];
 
        }
        // finalize the statement to release its resources
        sqlite3_finalize(statement);
    }
    else {
        NSLog(@"Problem with the database:");
        NSLog(@"%d",sqlResult);
    }
    
    return products;
    
}
@end

 

3、

#import <sqlite3.h> 

sqlite3 *contactDB;
   NSString *docsDir;
    NSArray *dirPaths;
    
    // Get the documents directory
    dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    
    docsDir = [dirPaths objectAtIndex:0];
    
    // Build the path to the database file
    NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"contacts.db"]];

    NSFileManager *filemgr = [NSFileManager defaultManager];
    
    if ([filemgr fileExistsAtPath:databasePath] == NO) 
    {
        const char *dbpath = [databasePath UTF8String];
        if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK) 
        {
            char *errMsg;
            const char *sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT,PHONE TEXT)";
            if (sqlite3_exec(contactDB, sql_stmt, NULL, NULL, &errMsg)!=SQLITE_OK) {
                status.text = @"創建表失敗\n";
            }
        }
        else 
        {
            status.text = @"創建/打開數據庫失敗";
        }
    }

 

4、向數據庫插入數據:

- (IBAction)SaveToDataBase:(id)sender 
{
    sqlite3_stmt *statement;
    
    const char *dbpath = [databasePath UTF8String];
    
    if (sqlite3_open(dbpath, &contactDB)==SQLITE_OK) {
        NSString *insertSQL = [NSString stringWithFormat:@"INSERT INTO CONTACTS (name,address,phone) VALUES(\"%@\",\"%@\",\"%@\")",name.text,address.text,phone.text];
        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(contactDB, insert_stmt, -1, &statement, NULL);
        if (sqlite3_step(statement)==SQLITE_DONE) {
            status.text = @"已存儲到數據庫";
            name.text = @"";
            address.text = @"";
            phone.text = @"";
        }
        else
        {
            status.text = @"保存失敗";
        }
        sqlite3_finalize(statement);
        sqlite3_close(contactDB);
    }
}

5、查詢數據庫庫:

- (IBAction)SearchFromDataBase:(id)sender 
{
    const char *dbpath = [databasePath UTF8String];
    sqlite3_stmt *statement;
    
    if (sqlite3_open(dbpath, &contactDB) == SQLITE_OK) 
    {
        NSString *querySQL = [NSString stringWithFormat:@"SELECT address,phone from contacts where name=\"%@\"",name.text];
        const char *query_stmt = [querySQL UTF8String];
        if (sqlite3_prepare_v2(contactDB, query_stmt, -1, &statement, NULL) == SQLITE_OK) 
        {
            if (sqlite3_step(statement) == SQLITE_ROW) 
            {
                NSString *addressField = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
                address.text = addressField;
                
                NSString *phoneField = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1    )];
                phone.text = phoneField;
                
                status.text = @"已查到結果";
                [addressField release];
                [phoneField release];
            }
            else {
                status.text = @"未查到結果";
                address.text = @"";
                phone.text = @"";
            }
            sqlite3_finalize(statement);
        }
        
        sqlite3_close(contactDB);
    }
}

 

使用:

    //  Get the DBAccess object;
    DBAccess *dbAccess = [[DBAccess alloc] init];
    
    //  Get the products array from the database
    self.products = [dbAccess getAllProducts];
    
    //  Close the database because we are finished with it
    [dbAccess closeDatabase];

 

tips:

1、讀取文件:

NSString *textFileContents = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myTextFile" ofType:@"txt"] 
encoding:NSUTF8StringEncoding error:
&error]; // If there are no results, something went wrong if (fileContents == nil) { // an error occurred   NSLog(@"Error reading text file. %@", [error localizedFailureReason]); } NSArray *lines = [textFileContents componentsSeparatedByString:@"\n"];
NSLog(@"Number of lines in the file:%d", [lines count] );

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM