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] );

 

转载于:https://www.cnblogs.com/shangdahao/archive/2013/05/29/3104053.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
步科触摸屏的函数脚本说明 目 录 1. KingSCADA的条件事件脚本等系统脚本中不能调用画面内部的对象吗? ...1 2. 我想在一个画面中调用另一个画面的内部对象,怎样做?............................1 3. 画面自定义变量和属性除了能被本画面的图素引用,其他的画面能引用吗? .............................................................................................................................................3 4. 导航图应用有EnableNavigate()和ShowNavigateWindow()两个函数,他们有什 么区别?.............................................................................................................................3 5. KingSCADA 提 供 保 存 画 面 的 函 数 , 如 SavePictureToFile() 、 SaveWholePictureToFile()函数,我写在按钮命令语言里为什么不执行?..................3 6. 利用表格模板和SQLCreateTable()函数创建数据库表格,为什么创建不成 功?.....................................................................................................................................3 7. 用SQLDropTable()函数删除一个数据库表格,为什么删不掉? ....................3 8. 用SQLGetRecord()函数为什么不能返回当前选择集中的指定序号的记录? 3 9. 用VarRefAddress函数不能实现变量的引用?..................................................4 10. KingSCADA运行系统怎样得到当前产生的报警数量? .................................4 11. 怎样从实时报警窗中手动删除确认过的报警记录?......................................5 12. KingSCADA可以实现通过弹出对话框让用户选择文件的功能吗? .............5 13. 有累计计算脚本,长时间运行后,累计值不变?..........................................6 14. FileWriteStr(“c:\sql.txt”,0,“sfd%”,0);但是输出文本里少了%?........................6 15. 在应用程序启动时脚本里添加了打开画面函数,运行时,画面没有打开? .............................................................................................................................................6 16. KS工程里有数据库查询或插入的脚本,长时间运行后,不能查询或插入记 录?.....................................................................................................................................6 17. KingSCADA的全局脚本、局部脚本有大小的限制吗? .................................6 18. KingSCADA中怎样实现把同一类型的文件名显示在列表框中?类似于组态 王的ListLoadFileName()函数的功能。............................................................................6 19. 怎样在KingSCADA运行时获取加密锁序列号? ............................................7 20. 通过调用数据集函数KDBGetDataset()对access数据库进行操作时,一直 报错“对象关闭时,不允许操作。 DBAccess: Open the source recordset failed!”?.7 21. 图素对象属性中的hotkey热键作用?...............................................................7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值