SQLite3 基本使用方法(二)

工程目录:

Singleton.h

//.h

#define single_interface(class) + (class *)shared##class;

//.m
// \ 代表下一行也属于宏
// ##是分隔符
#define single_implementation(class) static class *_instance; + (class *)shared##class {     if (_instance == nil) {         _instance = [[self alloc] init];     }     return _instance; }  + (id)allocWithZone:(NSZone *)zone {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _instance = [super allocWithZone:zone];     });     return _instance; }

MSUserManager.h

#import <Foundation/Foundation.h>
#import "MSUser.h"
#import <sqlite3.h>
#import "Singleton.h"

@interface MSUserManager : NSObject
{
     sqlite3 * m_pDb;
}

single_interface(MSUserManager)

//增
-(void) addUser:(MSUser *)user;

//删
-(void) deleteUser:(NSInteger)UserId;

//改
- (void)updateUser:(MSUser *)user;

//查
-(NSMutableArray *)allUser;

@end

MSUserManager.m

#import "MSUserManager.h"
#import <sqlite3.h>

@implementation MSUserManager   //单例
single_implementation(MSUserManager)

//在初始化方法中完成数据库链接工作
- (id)init
{
    self = [super init];

    if (self) {

        //1. 创建数据库
        [self openDB];
        //2. 创建数据库表
        [self createTable];

    }

    return self;
}

//打开数据库,如不存在,则创建。
- (void) openDB
{
    //生成存放在沙盒中的数据库完整路径
    NSString * strDocDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString * strDbName = [strDocDir stringByAppendingPathComponent: @"mySqlite3DB.db"];

    //sqlite3 数据库的链接,基于该链接可以进行数据库操作
    if (SQLITE_OK == sqlite3_open(strDbName.UTF8String, &m_pDb))
    {
        NSLog(@"创建/打开数据库成功!");
    }
    else
    {
        NSLog(@"创建/打开数据库失败!");
    }
}

//创建数据库表
//使用DBMANAGE创建,把生成的代码赋值过来就OK了。
//表名:tbl_User
//IF NOT EXISTS

//IOS 把id设为自增,在添加数据的时候,也要用null站位,不能不写。
- (void) createTable
{
    NSString * strSql = @"CREATE TABLE IF NOT EXISTS tbl_User (Id integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,UserName text,UserPass text)";

    char * pErrorMsg;
    if (SQLITE_OK ==  sqlite3_exec(m_pDb, strSql.UTF8String, NULL, NULL, &pErrorMsg)) {
        NSLog(@"创建数据表成功!");
    }
    else
    {
        NSLog(@"创建数据表失败!");
    }

}

- (void) execSql:(NSString *)sql msg:(NSString*)msg
{
    char * pErrorMsg;
    if (SQLITE_OK ==  sqlite3_exec(m_pDb, sql.UTF8String, NULL, NULL, &pErrorMsg))
    {
        NSLog(@"%@成功!", msg);
    }
    else
    {
        NSLog(@"%@失败 - %s!", msg, pErrorMsg);
    }
}

#pragma mark - 成员方法

//增
-(void) addUser:(MSUser *)user
{
    NSString * strSql = [NSString stringWithFormat: @"INSERT INTO tbl_User VALUES (null, ‘%@‘, ‘%@‘)",
                         user.UserName   , user.UserPass];

    [self execSql:strSql msg:@"添加"];

}

//删
-(void) deleteUser:(NSInteger)UserId
{
    //和增同理
}

//改
- (void)updateUser:(MSUser *)user
{
    //和增同理
}

//查
-(NSMutableArray *)allUser
{
    NSString * strSql = @"SELECT * FROM tbl_User";

    NSMutableArray * arrReturn = nil;

    //1. 评估准备SQL语法是否正确
    sqlite3_stmt * pStmt = NULL;
    if (SQLITE_OK == sqlite3_prepare_v2(m_pDb, strSql.UTF8String, -1, &pStmt, NULL))
    {
        arrReturn = [NSMutableArray array];

        //2. 如果能正常查询,调用单步执行方法, 依次取得查询结果
        //如果得到一行记录
        while (SQLITE_ROW == sqlite3_step(pStmt))
        {
            //3.获取/显示查询结果
            int nId = sqlite3_column_int(pStmt, 0);
            const unsigned char * pUserName = sqlite3_column_text(pStmt, 1);
            NSString * pUserNameUTF8 = [NSString stringWithUTF8String:(const char *)pUserName];
            const unsigned char * pUserPass = sqlite3_column_text(pStmt, 2);
            NSString * pUserPassUTF8 = [NSString stringWithUTF8String:(const char *)pUserPass];

            MSUser * pUser = [MSUser UserWithId:nId name:pUserNameUTF8 pass:pUserPassUTF8];

            [arrReturn addObject:pUser];
        }
    }
    else
    {
        NSLog(@"sql语法错误!");
    }
    //4. 释放句柄
    sqlite3_finalize(pStmt);

    return arrReturn;
}

@end

MSUser.h

#import <Foundation/Foundation.h>

@interface MSUser : NSObject

//工厂方法

//return User信息
+(id) UserWithId:(NSInteger)nId name:(NSString *)strUserName pass:(NSString *)strUserPass;

@property (assign , nonatomic) NSInteger Id;
@property (strong , nonatomic) NSString * UserName;
@property (strong , nonatomic) NSString * UserPass;

@end

MSUser.m

#import "MSUser.h"

@implementation MSUser

+(id) UserWithId:(NSInteger)nId name:(NSString *)strUserName pass:(NSString *)strUserPass
{
    MSUser * pUser = [[MSUser alloc] init];
    pUser.Id = nId;
    pUser.UserName = strUserName;
    pUser.UserPass = strUserPass;
    return pUser;
}

//
- (NSString *)description
{
    return [NSString stringWithFormat:@"< MSUser:%p  Id:%i  UserName:(%@)  UserPass:(%@) >",
           self, _Id, _UserName, _UserPass];
}

@end

MSViewController.m

#import "MSViewController.h"
#import "MSUserManager.h"
#import "MSUser.h"

@interface MSViewController ()

@end

@implementation MSViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    m_arrUser = [[MSUserManager sharedMSUserManager] allUser];
    NSLog(@"%@", m_arrUser);

}

@end

  

总结:

  1. 分层结构比较清晰, Model(User) -- Service(UserManager) -- Controller 。 有木有 像三层架构 呢。。。

  2. 单例类,需要理解! 有什么好处?特点?

SQLite3 基本使用方法(二)

时间: 2024-10-13 12:57:47

SQLite3 基本使用方法(二)的相关文章

SQLite3数据库恢复方法总结

最近做SQLite 3数据库的恢复,找了比较多相关方面的论文,在这里记录一下. 一.基于SQLite 文件系统的恢复 上一篇文章中,记录了SQLite 3的文件结构,里面提到了一点数据库中记录单元删除前后的底层变化,但是不太详细.在这里详细讲一下. SQLite 3数据库的删除与PC的文件系统数据的删除有些类似,就是删除的过程中,原始数据是不会被删除的,它会存留在底层,直到新的数据存储时覆盖掉.另外,在删除的过程中,当删除的记录单元较多时,数据库会整合自由块,这样一个自由块就可能包含多个记录单元

获得执行计划方法二-explain plan

1 安装 $ORACLE_HOME/rdbms/admin/utlxplan.sql (UNIX)  脚本生成一个表这个程序会创建一个名为plan_table的表 2 运行 explain PLAN [ SET STATEMENT_ID [=] < string literal > ] [ INTO < table_name > ] FOR < sql_statement > 其中: STATEMENT_ID:是一个唯一的字符串,把当前执行计划与存储在同一PLAN中的其

java-第十四章-代参的方法(二)-实现MyShopping系统的添加会员功能

 package com.wxws.sms; public class Customer {  int No;  int integarl; } package com.wxws.sms; public class Customers {  Customer[] customers = new Customer[100];  public void add(Customer cust){   for (int i = 0; i <customers.length; i++) {    if (c

java-第十四章-代参的方法(二)-查找会员积分

 package com.wxws.smsB; public class Customer {  int No;  int integarl; } package com.wxws.smsB; public class Customers {  Customer[] customers = new Customer[100];  public void add(Customer cust) {   for (int i = 0; i < customers.length; i++) {    i

Java-第十四章-代参的方法(二)-编程实现,输入班里10名学生的身高,获得身高最高的学生要求对象数组类型方法

package com.ww.yzpA; public class Students { int No; int Height; } package com.ww.yzpA; public class Height { public Students getMaxHeigth(Students[] str) { Students A = new Students(); for (int i = 0; i < str.length; i++) { if (str[i].Height > A.He

1-2+3-4+........+M方法一;方法二

1-2+3-4+......+m=(1-2)+(3-4)+...+[(m-2)-(m-1)]+m=-1+(-1)+(-1)+...+(-1)+m,一共有(m-1)/2个-1相加,再加上m,所以上式等于:(-1)*(m-1)/2+m代码:function sum(m as integer)sum=(-1)*(m-1)/2+mend function 1-2+3-4+........+M方法一:方法二,布布扣,bubuko.com

Javascript 正确使用方法 二

好的,废话不多说,接着上篇来. 变量(variables) 始终使用 var 关键字来定义变量,如果不这样将会导致 变量全局化,造成污染. //bad superPower = new SuperPower(); //good var superPower = new SuperPower(); 使用 一个 var关键字来定义多个变量...并且每个变量一行.. // bad var items = getItems(); var goSportsTeam = true; var dragonba

多台linux无密码访问之方法二

一:实验环境同"多台linux无密码访问之方法一" 二:配置过程 前3步同"多台linux无密码访问之方法一" ★第四步不同于方法一 4.在.ssh目录下创建一个名为config的文件并设置正确权限 manager:~/.ssh # touch config manager:~/.ssh # cat config StrictHostKeyChecking no UserKnownHostsFile /dev/null manager:~/.ssh # chmod

Cocos2d-x 精灵碰撞检測(方法二)

将"Cocos2d-x 精灵碰撞检測(方法一)" update函数改动一下. 使用精灵boundingBox函数获取直接精灵边界框, 不用自己计算精灵矩形大小了,还比較精确,然后调用intersectsRect计算2个精灵矩形是否存在交集. 代码: void HelloWorld::update(float delta) { //返回精灵边界框 CCRect cr1 = sp1->boundingBox(); CCRect cr2 = sp2->boundingBox();