как да добавите NSDictionary в ред на таблица в sqlite DataBase

Аз съм нов в разработката на iphone. Искам да съхраня един NSDictionary в ред на таблица sqlite. Търсих в Google и намерих много резултати, но не работи за мен.

това е моят речник:

NSDictionary * dic = [NSDictionary dictionaryWithObjectsAndKeys:@"24",@"id",@"Folder",@"name",@"300 MB",@"size", nil];

също търсих в този сайт, но не разбирам нищо в подобни публикации. моля, обяснете ми повече за добавяне (съхранение) NSDictionary в ред на таблица SQLite DB.


person estefan    schedule 01.05.2013    source източник
comment
Ще трябва да кодирате речника (като JSON или plist може би) и да го съхраните в базата данни.   -  person dreamlax    schedule 01.05.2013
comment
моят дявол, мога да кодирам този речник в plist, но как да го съхраня (plist) в база данни???   -  person estefan    schedule 01.05.2013


Отговори (3)


можете да направите това, като създадете таблица с три колони (използване на заявка за създаване на таблица). И след това вмъкнете тези обекти от вашия речник в тези колони (използвайки заявка за вмъкване).

Редактиране: За вмъкване на данни използвайте заявка:

            NSString *query = [NSString stringWithFormat:@"insert into tablename (column1, column2,column3) values('%@','%@','%@')",[dic objectForKey:@"id"],[dic objectForKey:@"name"],[dic objectForKey:@"size"]];
            NSLog(@"query : %@",query);
            [self executeQuery:query];

В .h клас направете екземпляр на sqlite:

sqlite3 *database; and import:  #import<sqlite3.h>

В .m клас направете добавяне на тези методи:

-(NSString *) dataFilePath
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSLog(@"PATH %@",[documentsDirectory stringByAppendingPathComponent:DatabaseName]);
    return [documentsDirectory stringByAppendingPathComponent:DatabaseName];
}

/*==================================================================
              METHOD FOR INSERTING DATA IN DATABASE
 ==================================================================*/
-(void)executeQuery:(NSString *)query
{
    //NSLog(@"QUERY : %@",query);

    sqlite3_stmt *statement;
    if(sqlite3_open([[self dataFilePath] UTF8String], &database) == SQLITE_OK)
    {
        if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, NULL) == SQLITE_OK)
        {
            if (sqlite3_step(statement) != SQLITE_DONE)
            {
                sqlite3_finalize(statement);
            }
        }
        else
        {
            NSLog(@"query Statement Not Compiled");
        }

        sqlite3_finalize(statement);
        sqlite3_close(database);
    }
    else
    {
        NSLog(@"Data not Opened");
    }
}

За четене на данни:

/*==================================================================
 METHOD FOR Fetching Data FROM DATABASE
 ==================================================================*/
 NSString *query = [NSString stringWithFormat:@"select * from table_name"];
NSMutableArray *tableData = [self fetchingDataFromTable:query];

// Тук масивът от данни на таблицата съдържа всички записи

-(NSMutableArray *)fetchingDataFromTable:(NSString *)query;
{
    NSLog(@"QUERY : %@",query);

    NSString *idToReturn=@"";
    NSMutableArray *returnArray = [NSMutableArray new];
    if(sqlite3_open([[self dataFilePath] UTF8String], &database) == SQLITE_OK)
    {
        sqlite3_stmt *statement;
        if (sqlite3_prepare_v2(database, [query UTF8String], -1, &statement, nil)==SQLITE_OK)
        {
            while(sqlite3_step(statement)==SQLITE_ROW)
            {
                NSMutableDictionary *temp= [NSMutableDictionary new];
                const char *s;


                s=(char *)sqlite3_column_text(statement, 0);
                if(s==NULL)
                {
                    idToReturn=@"";
                }
                else
                {
                    idToReturn =[NSString stringWithUTF8String:s];
                }
                [temp setObject:idToReturn forKey:@"id"];

                s=(char *)sqlite3_column_text(statement, 1);
                if(s==NULL)
                {
                    idToReturn=@"";
                }
                else
                {
                    idToReturn =[NSString stringWithUTF8String:s];
                }
                [temp setObject:idToReturn forKey:@"name"];

                s=(char *)sqlite3_column_text(statement, 2);
                if(s==NULL)
                {
                    idToReturn=@"";
                }
                else
                {
                    idToReturn =[NSString stringWithUTF8String:s];
                }
                [temp setObject:idToReturn forKey:@"size"];

                if (temp != nil)
                {
                    [returnArray addObject:temp];

                    temp = nil;
                }

            }
            sqlite3_finalize(statement);
            sqlite3_close(database);
        }
    }
    return returnArray;

}

Дано ти помогне.

person Nishant Tyagi    schedule 01.05.2013
comment
Благодаря ти скъпи приятелю. Създавам таблица DB с три колони с имена (id, name, size) и това ниво какво правя??? можете ли да ми обясните повече за (използване на заявка за вмъкване) с код!!! Благодаря ти много. - person estefan; 01.05.2013
comment
приятелю, давам тази заявка за грешка Statement Not Compiled защо? - person estefan; 01.05.2013
comment

Имам проблеми с внедряването на логиката на хранилището. В реален проект използвам Ninject, така че използвам интерфейси за някои класове. Засега направих много проста демонстрация на проблема:

// ------- Base User -------------- //

public interface IBaseUser
{
    int Id { get; set; }
}
public class BaseUser : IBaseUser
{
    public int Id { get; set; }
}

// -------- Individual User --------//

public interface IIndividualUser : IBaseUser
{
    string Gender { get; set; }
}
public class IndividualUser: BaseUser, IIndividualUser
{
    public string Gender { get; set; }
}

// -------- Legal User --------//

public interface ILegalUser : IBaseUser
{
    string VatNumber { get; set; }
}
public class LegalUser : BaseUser, ILegalUser
{
    public string VatNumber { get; set; }
}

// -------- Base User Repo --------//

public interface IBaseUserRepo<T> where T: BaseUser
{
    T GetById(int id);
}
public class BaseUserRepo<T> where T : BaseUser, IBaseUserRepo<T>
{
    public T GetById(int id)
    {
        // logic...
    }
}

// -------- Individual User Repo --------//

public interface IIndividualUserRepo : IBaseUserRepo<IndividualUser>
{
    IndividualUser GetByGender(string gender);
}
public class IndividualUserRepo : BaseUserRepo<IndividualUser>, IIndividualUserRepo
{
    public IndividualUser GetByGender(string gender)
    {
        // logic...
    }
}

// -------- Legal User Repo --------//

public interface ILegalUserRepo : IBaseUserRepo<LegalUser>
{
    LegalUser GetByVatNumber(string vatNumber);
}
public class LegalUserRepo : BaseUserRepo<LegalUser>, ILegalUserRepo
{
    public LegalUser GetByVatNumber(string vatNumber)
    {
        // logic...
    }
}

В тези 2 реда код:

public class IndividualUserRepo : BaseUserRepo<IndividualUser>, IIndividualUserRepo

public class LegalUserRepo : BaseUserRepo<LegalUser>, ILegalUserRepo

компилаторът изстрелва тези грешки:

Типът „genericInterfaceTest.IndividualUser“ не може да се използва като параметър на типа „T“ в общия тип или метод „genericInterfaceTest.BaseUserRepo“. Няма имплицитно преобразуване на препратка от 'genericInterfaceTest.IndividualUser' към 'genericInterfaceTest.IBaseUserRepo'. C:\Work\Tests\genericInterfaceTest\genericInterfaceTest\Program.cs 77 18 genericInterfaceTest

и

Типът „genericInterfaceTest.LegalUser“ не може да се използва като параметър на типа „T“ в общия тип или метод „genericInterfaceTest.BaseUserRepo“. Няма имплицитно преобразуване на препратка от 'genericInterfaceTest.LegalUser' към 'genericInterfaceTest.IBaseUserRepo'. C:\Work\Tests\genericInterfaceTest\genericInterfaceTest\Program.cs 91 18 genericInterfaceTest

Това се случва само тогава, когато внедрявам интерфейса IBaseUserRepo в този ред код:

public class BaseUserRepo<T> where T : BaseUser, IBaseUserRepo<T>

Може ли някой да ми обясни, моля, къде греша.

- person estefan; 01.05.2013
comment
също как да прочета тези данни от sqlite?? благодаря ви много, ако отговорите на два въпроса, майсторе... :-* - person estefan; 01.05.2013
comment
Да, можете да добавите толкова, колкото имате нужда. Можете да използвате цикъл и след това да използвате заявка за вмъкване за многократно вмъкване. - person Nishant Tyagi; 01.05.2013
comment
мой приятел, добавям този код в моето приложение. как да разбера четене от sqlite??? съхранява в NSMutableArray *returnArray??? - person estefan; 01.05.2013
comment
Еха!!! Скъпи приятелю, толкова съм объркан!!! какво правя, че веднъж съхранявам (при първо стартиране на приложение) този NSDictionary в таблица sqlite и след поредица от данни за проверка, ако съществуват в sqlite, не добавям... - person estefan; 01.05.2013
comment
@NishantTyagi Получавам тази заявка за грешка Statement Not Compiled защо? Можете ли да ми предложите какво правя погрешно. Създавам таблица DB с три колони с имена (id, name, size). - person Dilip Mishra; 02.06.2021
comment
@NishantTyagi Освен това получавам празни данни, когато се справям, че използвам същия код. - person Dilip Mishra; 03.06.2021

Създадох динамичен код, който ще върне списък с всички колони с всички редове

 -(NSMutableDictionary*)getRowsFromTableName:(NSString*)tableName
 {
 NSString *databasePath =[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]
//                         stringByAppendingPathComponent: @"sqlcipher.db"];
 sqlite3 *db;
 bool sqlcipher_valid = NO;
 NSMutableDictionary *dbData = [[NSMutableDictionary alloc]init];
 NSMutableArray *columnList = [[NSMutableArray alloc]init];

 if (sqlite3_open([databasePath UTF8String], &db) == SQLITE_OK) {
    const char* key = [keyString UTF8String];
    sqlite3_key(db, key, strlen(key));
    if (sqlite3_exec(db, (const char*) "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL) == SQLITE_OK) {
        if(sqlite3_prepare_v2(db, "PRAGMA cipher_version;", -1, &stmt, NULL) == SQLITE_OK) {
            if(sqlite3_step(stmt)== SQLITE_ROW) {
                const unsigned char *ver = sqlite3_column_text(stmt, 0);
                if(ver != NULL) {
                    sqlcipher_valid = YES;

                    // password is correct (or database initialize), and verified to be using sqlcipher
                    char *errMsg;
                    const char *query = [[NSString stringWithFormat:@"select * from %@",tableName] UTF8String]; //where name = 'abc'";
                    if (sqlite3_exec(db, query, NULL, NULL, &errMsg)
                        != SQLITE_OK)
                    {
                        // isSuccess = NO;
                        NSLog(@"Failed to open data into table");
                        [dbData setValue:@"Failed to open data into table" forKey:@"Message"];
                        [dbData setValue:@"Failed" forKey:@"status"];
                        return dbData;
                    }
                    else
                    {
                        NSLog(@"Data open Successfully");
                        int num_cols;
                        if(sqlite3_prepare_v2(db, query, -1, &stmt, NULL) == SQLITE_OK) {

                            while (sqlite3_step(stmt) == SQLITE_ROW)
                            {
                                num_cols = sqlite3_data_count(stmt);
                                NSMutableDictionary *columnDic = [[NSMutableDictionary alloc]init];
                                for (int i = 1; i < num_cols; i++) {
                                    NSString *colValue = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, i)];
                                    NSString *colName = [NSString stringWithUTF8String:(char*)sqlite3_column_name(stmt, i)];
                                    [columnDic setValue:colValue forKey:colName];
                                    NSLog(@"%@",columnDic);
                                }
                                [columnList addObject:columnDic];
                                columnDic = nil;
                            }
                            NSLog(@"%@",columnList);
                            [dbData setValue:columnList forKey:@"data"];

                        }
                    }
                }
            }
            else
            {
                NSLog(@"Error while binding variable. '%s'", sqlite3_errmsg(db));
                [dbData setValue:[NSString stringWithFormat:@"Error while binding variable. '%s'", sqlite3_errmsg(db)] forKey:@"Message"];
                [dbData setValue:@"Failed" forKey:@"status"];
                return dbData;
            }
            sqlite3_finalize(stmt);
        }
        else
        {
            NSLog(@"Error while creating update statement. '%s'", sqlite3_errmsg(db));
            [dbData setValue:[NSString stringWithFormat:@"Error while creating update statement. '%s'", sqlite3_errmsg(db)] forKey:@"Message"];
            [dbData setValue:@"Failed" forKey:@"status"];
            return dbData;
        }
    }
    else
    {
        NSLog(@"Error while creating update statement. '%s'", sqlite3_errmsg(db));
        [dbData setValue:[NSString stringWithFormat:@"Error while creating update statement. '%s'", sqlite3_errmsg(db)] forKey:@"Message"];
        [dbData setValue:@"Failed" forKey:@"status"];
        return dbData;
    }
    sqlite3_close(db);
}
NSLog(@"%@",dbData);

return dbData;

}

person Chaaruu Jadhav    schedule 15.07.2017

И вземете данни в речника от таблицата в iOS:

-(void)getData:(NSString *) tablename
{
    NSMutableDictionary * tabledata= [[NSMutableDictionary alloc] init];
    NSString *str = @"select * from ";
    NSString *strQuery = [str stringByAppendingString:tablename];
    tabledata = [db executeQuery:strQuery];

    NSDictionary *dic = [tabledata valueForKey:@"0"];
    NSLog(@"dic is:%@",dic);
}
person jevin ambaliya    schedule 20.04.2016