2016-12-01 11:01:21 onlychengzhi 阅读数 194
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    27325课时 0分钟 71人学习 田果果
    免费试看
123
2018-01-11 13:52:00 weixin_30826095 阅读数 0
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    27325课时 0分钟 71人学习 田果果
    免费试看

一个可以直接连接服务器MySQL的工具包(极不安全,如非特殊需求,不推荐使用)

这种直接连接服务器数据的方式是极为不安全的,但因为我们这个项目特殊情况,只在局域网内使用, 且只有一个pad对一台设备进行唯一的控制,不存在网络安全问题和其他设备干扰问题,故而最终采用 这种方式进行和设备的直接通讯。

github地址:https://github.com/SZLCode/MySQLConManager/tree/master 

 

转载于:https://www.cnblogs.com/shizhiliblog/p/8268052.html

2017-01-31 10:12:36 werctzzz 阅读数 2665
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    27325课时 0分钟 71人学习 田果果
    免费试看

在iOS开发中,除了UI页面以外使用最多的估计是数据对象的存储了~比如聊天记录、通讯录和通讯记录、浏览记录等等。我们要根据不同的使用方式去对这些数据存储并使用。常用的有:①沙盒机制 ②属性列表plist ③SQLite ④CoreData,本文介绍的就是基础的SQLite的存储机制,其他的稍后会陆续跟进~


一、首先要注意SQLite的特性:无数据类型的数据库,所以和在别的平台上的SQL会有一定的差距

二、常用数据类型

· integer有符号的整数类型

· text字符串类型

· real浮点类型

· blob二进制对象类型

三、在项目中创建数据库

①在项目中引入sql支持库:libsqlite3.tbd,还有一个3.0的,我个人用3,不要问我为什么啊(╯‵□′)╯︵┻━┻

②配置数据库,创建两个NSObject类,一个作为model 一个作为数据库操作


假设我们只存储两个数据,一个是又textview写入的文本,一个是当前时间

DataModel.h文件
#import <Foundation/Foundation.h>

@interface DataModel : NSObject

// 用来接收文本的属性
@property (nonatomic , copy)NSString * text;
// 文本保存时间
@property (nonatomic , strong)NSDate * date;

// 文本初始化
-(id)initWithText:(NSString *)text Date:(NSDate*)date;

@end

DataModel.m文件
#import "DataModel.h"

@implementation DataModel

-(id)initWithText:(NSString *)text Date:(NSDate*)date{
    self = [super init];
    if (self) {
        self.text = text;
        self.date = date;
    }
    return self;
}

@end
针对数据库的操作就是通过DBOperation来完成,包括表的创建和数据库连接以及各项操作
DBOperation.h文件
#import <Foundation/Foundation.h>
// 引入model
#import "DataModel.h"
// 引入sql的支持库
#import "sqlite3.h"

// 数据库文件名
#define DB_Name @"Database.sqlite3"

@interface DBOperation : NSObject
{
    // 数据库对象的成员变量
    sqlite3 * database;
}

// 创建一个管理器
+ (DBOperation *)DataBaseManager;
// 数据库文件路径
- (NSString *)Documentsfilepath;
// 打开数据库、创建数据库表
- (void)createDataBaseTable;

// 添加
-(int)addData:(DataModel*)model;
// 删除
-(int)deleteData:(DataModel*)model;
// 修改
-(int)editData:(DataModel*)model;
// 查询
-(NSMutableArray*)selectall;

@end

DBOperation.m文件
#import "DBOperation.h"

@implementation DBOperation

// 创建一个静态变量
static DBOperation * DataBaseManager = nil;

+ (DBOperation*)DataBaseManager
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        
        DataBaseManager = [[self alloc] init];
        [DataBaseManager createDataBaseTable];
        
    });
    return DataBaseManager;
}

// 创建一个数据库,创建名为Text的表设定一个content的属性
- (void)createDataBaseTable {
    NSString *writableDBPath = [self Documentsfilepath];
    const char* charpath = [writableDBPath UTF8String];
    
    if (sqlite3_open(charpath, &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(NO,@"数据库打开失败");
    } else {
        char *err;
        // 创建一个数据库表,名为 Text  并添加两个元素 其中textdate为主键
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Text (textdate TEXT PRIMARY KEY, content TEXT);"];
        const char* charSql = [sql UTF8String];
        
        if (sqlite3_exec(database, charSql,NULL,NULL,&err) != SQLITE_OK) {
            sqlite3_close(database);
            NSAssert(NO, @"建表失败");
        }
        sqlite3_close(database);
    }
}

// 数据库存放路径
- (NSString *)Documentsfilepath {
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [documentDirectory stringByAppendingPathComponent:DB_Name];
    
    return path;
}

//添加方法
-(int)addData:(DataModel *)model
{
    
    NSString *path = [self Documentsfilepath];
    const char* charpath = [path UTF8String];
    
    if (sqlite3_open(charpath, &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(NO,@"数据库打开失败。");
    } else {
        
        NSString *sql = @"INSERT OR REPLACE INTO Text (textdate, content) VALUES (?,?)";
        const char* charSql = [sql UTF8String];
        
        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
            
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char* charDate  = [strDate UTF8String];
            
            const char* charContent = [model.text UTF8String];
            
            //绑定参数开始
            sqlite3_bind_text(statement, 1, charDate, -1, NULL);
            sqlite3_bind_text(statement, 2, charContent, -1, NULL);
            
            //执行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"插入数据失败。");
            }
        }
        sqlite3_finalize(statement);
        sqlite3_close(database);
    }
    return 0;
}

//删除方法
-(int)deleteData:(DataModel *)model
{
    NSString *path = [self Documentsfilepath];
    const char* charpath = [path UTF8String];
    
    if (sqlite3_open(charpath, &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(NO,@"数据库打开失败。");
    } else {
        NSString *sql = @"DELETE from Text where textdate =?";
        const char* charSql = [sql UTF8String];
        
        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *strDate = [dateFormatter stringFromDate:model.date];
            const char * charDate  = [strDate UTF8String];
            
            //绑定参数开始
            sqlite3_bind_text(statement, 1, charDate, -1, NULL);
            //执行
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"删除数据失败。");
            }
        }
        
        sqlite3_finalize(statement);
        sqlite3_close(database);
    }
    
    return 0;
}

//查询数据方法
-(NSMutableArray*)selectall
{
    NSMutableArray *listData = [[NSMutableArray alloc] init];
    
    NSString *path = [self Documentsfilepath];
    const char* charpath = [path UTF8String];
    
    if (sqlite3_open(charpath, &database) != SQLITE_OK) {
        sqlite3_close(database);
        NSAssert(NO,@"数据库打开失败。");
    } else {
        
        NSString *sql =@"SELECT textdate,content FROM Text";
        const char* charSql = [sql UTF8String];
        
        sqlite3_stmt *statement;
        //预处理过程
        if (sqlite3_prepare_v2(database, charSql, -1, &statement, NULL) == SQLITE_OK) {
            
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            
            //执行
            while (sqlite3_step(statement) == SQLITE_ROW) {
                char *bufDate = (char *) sqlite3_column_text(statement, 0);
                NSString *strDate = [[NSString alloc] initWithUTF8String: bufDate];
                NSDate *date = [dateFormatter dateFromString:strDate];
                
                char *bufContent = (char *) sqlite3_column_text(statement, 1);
                NSString * strContent = [[NSString alloc] initWithUTF8String: bufContent];
                
                DataModel * model = [[DataModel alloc] initWithText:strContent Date:date];
                
                [listData addObject:model];
            }
        }
        
        sqlite3_finalize(statement);
        sqlite3_close(database);
        
    }
    return listData;
}

@end

到目前为止数据库的处理就是基本完成了,剩下的就是去项目里面开始实际操作,为了方便写了一个DBManager用来管理引用数据库操作和model值得传递

DBManager.h文件
#import <Foundation/Foundation.h>
#import "DataModel.h"
#import "DBOperation.h"

@interface DBManager : NSObject

// 添加
-(NSMutableArray *)addTextdata:(DataModel*)model;
// 删除
-(NSMutableArray *)deleteTextdata:(DataModel*)model;
// 查询
-(NSMutableArray *)selectall;

@end

DBManager.m文件
#import "DBManager.h"
@implementation DBManager

// 这个类是用来作为媒介,可用可不用,只是为了让过程更加清晰

// 添加
-(NSMutableArray *)addTextdata:(DataModel *)model
{
    DBOperation * m = [DBOperation DataBaseManager];
    [m addData:model];
    return [m selectall];
}
// 删除
-(NSMutableArray *)deleteTextdata:(DataModel *)model
{
    DBOperation * m = [DBOperation DataBaseManager];
    [m deleteData:model];
    return [m selectall];
}

// 查询
-(NSMutableArray *)selectall
{
    DBOperation * m = [DBOperation DataBaseManager];
    return [m selectall];
}

@end
③我们回到页面创建的地方,开始创建视图,代码就不详细讲解了,在附上的demo中有很详细的注释,目前就是讲一个引导性的思路~在首页创建一个tableview,用来展示数据,通过nav上的button进入到add页面,直接调用DBManager的add方法,我在这里添加了一个消息中心,方便返回页面时候的传值。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton * addbtn = [[UIButton alloc]initWithFrame:CGRectMake(self.view.frame.size.width/2, 100, 120, 30)];
    addbtn.backgroundColor = [UIColor redColor];
    [addbtn setTitle:@"添加" forState:UIControlStateNormal];
    [addbtn addTarget:self action:@selector(add) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:addbtn];
    
    textview = [[UITextView alloc]initWithFrame:CGRectMake(0, 150, self.view.frame.size.width, 100)];
    textview.backgroundColor = [UIColor blueColor];
    [self.view addSubview:textview];
    // Do any additional setup after loading the view.
}

-(void)add{
    
    DBManager *manager = [[DBManager alloc] init];
    DataModel *model = [[DataModel alloc] init];
    model.date = [[NSDate alloc] init];
    model.text = textview.text;
    NSMutableArray *reslist = [manager addTextdata: model];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"backaction" object:reslist userInfo:nil];
    [self dismissViewControllerAnimated:NO completion:nil];
}

在首页先记得声明消息中心

[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reloadView:)
                                                 name:@"backaction"
                                               object:nil];

然后删除的方法我写在了tableview的编辑里面直接完成删除操作~

// 向左滑动可删除数据
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        DataModel * model = [self.listData objectAtIndex:[indexPath row]];
        DBManager * dm = [[DBManager alloc] init];
        self.listData = [dm deleteTextdata: model];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        
    }
}

四、也许有人会问我为什么增删改查没有“改”这一项,我想说我也不知道啊,如果知道的教教我~哈哈,正常来说都是网络请求的数据保存到本地做查询和删除,修改数据都是直接上传到服务器上面。表示没有做过需要在本地修改的数据库项目~(╯‵□′)╯︵┻━┻(我是菜鸡)

附上传送门:demo

2017-03-14 00:46:27 Ashimar_a 阅读数 1667
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    27325课时 0分钟 71人学习 田果果
    免费试看

当我们进行开发的时候,经常会查看APP的沙盒,看看数据库写入或文件存储是否正确,用模拟器run 的时候,我们那路径去通过文件夹访问是没问题的。但是通过真机的拿到的路径就无法通过电脑直接访问了,这时候要查看真机里面的沙盒应该怎么办呢?

当你进行真机测试时,将你的Demo run 到真机上,此时iPhone是连接到电脑的,我们通过Xcode来查看APP中的沙盒,步骤如下:

1、通过添加设备打开 Devices 界面,这时你可以看到你的手机信息及安装在你手机上的测试APP的信息。

2、找到你想查看的沙盒的APP,选中后点击设置按钮。

3、在弹出来的选项中,选择Download Container 选项。

4、现在之后的包点击右键显示包内容,即可看到沙盒文件内容。图文操作如图:

这里写图片描述

有帮助的顶一个哦❤️☺️✌️

2018-11-17 20:28:48 yan325098 阅读数 988
  • 采用全局过滤器ExceptionFilter实现AOP

    能够说出Rancher软件的作用,能够在Rancher中部署微服务 能够说出influxDB的作用,能够创建数据库、用户、赋予权限 能够说出cAdvisor 的作用,能够创建容器与influxDB连接 能够说出Grafana 的作用,能够使用Grafana...

    27325课时 0分钟 71人学习 田果果
    免费试看

前言:

不知道大家平时在iOS中需要查看数据库内容的时候是否有困扰,以前做法都是把数据库文件导出到电脑上,然后通过mac上的数据库可视化软件打开查看里面的数据。一来一回挺折腾的,不满于这种浪费时间效率低下的方式,所以想着要是能够直接在手机上或者模拟器上查看数据库多好,直接操作数据库多好,可以大大节省时间,提高工作效率。

实现:

  • 因为在iOS中的数据库存储大多是基于SQLite框架实现的,其他的比如Realm是有自己的一套数据库存储引擎,当然也有部分选择苹果自家的Core Data来实现的。在这里我只对基于SQLite实现的做了一个可视化的方案,后续可能会对其他存储引擎的支持。
  • 实现方式就是通过对sqlite的api一个封装可以支持通用的查询,删除,修改。这里暂时是没有做新增一行的功能。但也可以解决大部分查看数据源库,更新数据库的需求了。

效果可以看下图:
databasedemo.gif

  • 可以针对某一个table删除具体选中的一行,可以修改某一行某一个字段的值(当然主键除外)。我们都知道平常修改某一个行数据或者删除的话都要限定一个where条件,一般来说是去判断一个唯一标志的字段,但是我们并不能知道数据库的唯一标志是哪一个字段,或者有些数据库也是没有主键存在的,当然也可以罗列出当前行的所有字段去判断,这就有点费精力了,有些字段多的就需要判断很多。所以这里我用到了一个数据库的影藏字段rowid,通过这个rowid去找到我们具体要修改的哪一行,但是rowid是自增的并且不会重复出现的,如果删除了一条数据,后面新增的数据rowid也是会在原来的最大rowid上+1的,如果删除了某一行就会导致rowid和我们显示出来的row对应不上了,感觉才找到的一条路瞬间好像又有点走不通了,不过我们可以加上限制条件找出这一行的rowid,然后通过rowid去修改这一行的数据。比如要修改显示中的第三行数据可以通过这样的一个条件语句去判断“WHERE rowid IN (SELECT rowid FROM table limit 2,1)”。
  • update数据库的话也是通过上面的rowid去找到具体一行当做限定条件去修改,不过我们可视化显示出来都是字符串类型的,修改成自己想要的数据,传去update的时候再把string修改成对应字段所有对应的数据类型去update。

使用

CocoaPods

1.更新cocoapods到最新版本。
2.添加 pod ‘DatabaseVisual’ 到你的podfile文件中。
3.运行 pod install 或者 pod update.
4.import <DatabaseVisual/DatabaseManager.h>.

Manually

1.下载DatabaseManager文件夹.
2.添加源文件到你的项目工程.
3.import “DatabaseManager.h”

工具使用方法也超级简单,指定你当前存放数据库的文件夹就行了。会把文件夹下面的所有.db .sqlite .sqlite3后缀的文件显示出来。

//you can specify the folder where the database resides
[DatabaseManager sharedInstance].dbDocumentPath =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
[[DatabaseManager sharedInstance] showTables];

已经更新在github上。如果喜欢请给个?。
写得仓促,测试样本也不多,有什么问题请及时提给我。当然有什么好的建议也欢迎提给我,大家共同探讨做得更好。
后期应该会考虑加入Realm等其他存储方式的可视化。

最后附上 DatabaseVisual地址


欢迎转载,并注明出处