1. 创建数据库
1) 使用 FMDatabase创建
objectivec
复制代码
// 获取数据库路径
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
_dbPath = [docsDir stringByAppendingPathComponent:@"TestFMDB.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:_dbPath];
2) 使用FMDatabaseQueue 创建 FMDatabaseQueue // 线程安全的数据库队列
objectivec
复制代码
_dbQueue = [FMDatabaseQueue databaseQueueWithPath:_dbPath];
2 .创建表
1) 创建一个设置自动递增主键的表
objectivec
复制代码
NSString *createTableSQL = @"CREATE TABLE IF NOT EXISTS myTable (" @"id INTEGER PRIMARY KEY AUTOINCREMENT, " @"name TEXT, " @"age INTEGER");"
// 执行创建表操作
BOOL success = [db executeUpdate:createTableSQL];
if (success)
{
NSLog(@"表创建成功");
}
else
{
NSLog(@"表创建失败: %@", [db lastErrorMessage]);
}
2) 创建一个复合唯一约束的表
objectivec
复制代码
NSString *createTableSQL = @"CREATE TABLE IF NOT EXISTS AFDBTable ("
"deviceMac TEXT NOT NULL,"
"userId TEXT NOT NULL,"
"timestamp INTEGER," // 时间戳(整型)
"detailData TEXT,"
"CONSTRAINT unique_dev_user UNIQUE (dev_code, user_id) ON CONFLICT REPLACE"
// 复合唯一约束 复合约束的名称为 unique_dev_user ON CONFLICT REPLACE 当发生唯一约束冲突时,用新数据替换现有数据
")";
BOOL success = [db executeUpdate:createTableSQL];
if (!success) {
NSLog(@"创建表失败: %@", [db lastError]);
return;
}
3.插入数据
1) 普通的插入数据
objectivec
复制代码
//遇到冲突时替换
NSString* insertSql = @"INSERT OR REPLACE AFDBTable (deviceMac, userId, timestamp, detailData) VALUES (?, ?, ?, ?)";
// //遇到冲突时忽略
// insertSql = @"INSERT OR IGNORE AFDBTable (deviceMac, userId, timestamp, detailData) VALUES (?, ?, ?, ?)";
//
// //遇到冲突时终止
// insertSql = @"INSERT OR ABORT AFDBTable (deviceMac, userId, timestamp, detailData) VALUES (?, ?, ?, ?)";
// 在队列中执行操作
[_dbQueue inDatabase:^(FMDatabase *db) {
BOOL success = [db executeUpdate:insertSql,
@"AFBSADGA-ADFDF",
@"afdsfd",
@1768791520,
@"1,2,3,4,5"];
if(!success)
{
NSLog(@"插入或更新失败");
}
}];
2) 通过事务插入,如果其中一条插入失败,可以回滚到些事务执行之前的内容
objectivec
复制代码
//遇到冲突时替换
NSString* insertSql = @"INSERT OR REPLACE AFDBTable (deviceMac, userId, timestamp, detailData) VALUES (?, ?, ?, ?)";
[_dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
BOOL success1 = [db executeUpdate:insertSql,
@"AFBSADGA-ADFDF",
@"afdsfd",
@1768791520,
@"1,2,3,4,5"];
BOOL success2 = [db executeUpdate:insertSql,
@"AFBSADGA-ADFDF",
@"gggggggg",
@1768791520,
@"1,2,3,4,5"];
if(!(success1 && success2))
{
*rollback = YES;
NSLog(@"插入或更新失败");
}
}];
4.查询
objectivec
复制代码
NSMutableArray<NSDictionary *> *resultArray = [NSMutableArray array];
NSString *deviceMac = @"AFBSADGA-ADFDF";
NSString *userId = @"gggggggg";
if (!deviceMac || !userId) {
NSLog(@"deviceMac或userId不能为空");
[_dbQueue inDatabase:^(FMDatabase *db) {
NSString *querySQL = @"SELECT * FROM AFDBTable "
"WHERE deviceMac = ? AND userId = ? ;";
FMResultSet *rs = [db executeQuery:querySQL,
deviceMac,
userId];
while ([rs next]) {
NSMutableDictionary* dic = [NSMutableDictionary dictionary];
NSString* tmpStr = [rs stringForColumn:@"deviceMac"];
[dic setValue:tmpStr forKey:@"deviceMac"];
tmpStr = [rs stringForColumn:@"userId"];
[dic setValue:tmpStr forKey:@"userId"];
long timestamp = [rs longForColumn:@"timestamp"];
[dic setValue:@(timestamp) forKey:@"timestamp"];
tmpStr = [rs stringForColumn:@"detailData"];
[dic setValue:tmpStr forKey:@"detailData"];
[resultArray addObject:dic];
}
[rs close];
}];
5.常用的查询帮助方法
objectivec
复制代码
// 获取记录总数
int count = [database intForQuery:@"SELECT COUNT(*) FROM users"];
NSLog(@"用户总数: %d", count);
// 获取最大值
int maxAge = [database intForQuery:@"SELECT MAX(age) FROM users"];
NSLog(@"最大年龄: %d", maxAge);
// 获取平均值
double avgAge = [database doubleForQuery:@"SELECT AVG(age) FROM users"];
NSLog(@"平均年龄: %.1f", avgAge);
6.索引的使用
1.创建索引
objectivec
复制代码
if ([self.db beginTransaction]) {
@try {
// 创建用户名索引
[self.db executeUpdate:@"CREATE INDEX IF NOT EXISTS idx_users_name ON users(name)"];
// 创建邮箱唯一索引
[self.db executeUpdate:@"CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users(email)"];
// 创建复合索引(姓名+年龄)
[self.db executeUpdate:@"CREATE INDEX IF NOT EXISTS idx_users_name_age ON users(name, age)"];
// 创建条件索引
[self.db executeUpdate:@"CREATE INDEX IF NOT EXISTS idx_active_users ON users(last_login) WHERE is_active = 1"];
[self.db commit];
return YES;
} @catch (NSException *exception) {
[self.db rollback];
NSLog(@"创建用户索引失败: %@", exception);
return NO;
}
}
2. 查看所有索相
objectivec
复制代码
NSMutableArray *indexes = [NSMutableArray array];
FMResultSet *result = [self.db executeQuery:@"SELECT name, tbl_name, sql FROM sqlite_master WHERE type = 'index'"];
while ([result next]) {
NSMutableDictionary *indexInfo = [NSMutableDictionary dictionary];
indexInfo[@"name"] = [result stringForColumn:@"name"];
indexInfo[@"table"] = [result stringForColumn:@"tbl_name"];
indexInfo[@"sql"] = [result stringForColumn:@"sql"];
[indexes addObject:indexInfo];
}
[result close];
3.删除索引
objectivec
复制代码
[self.db executeUpdate:@"DROP INDEX IF EXISTS ?", indexName];