FMDBによるSQLite連携
広く使われているFMDBラッパーを利用して、Objective-CアプリにSQLiteデータベースを統合し、データを直接操作します。
「FMDBによるSQLite連携」はCoddyKit上の無料Objective-C iOS Development for Legacy & Enterprise Appsレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはObjective-C iOS Development for Legacy & Enterprise Apps学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Objective-C iOS Development for Legacy & Enterprise Appsコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
SQLite & FMDB: An Introduction
Welcome! In this lesson, we'll explore integrating SQLite, a popular lightweight database, directly into your Objective-C applications. SQLite is embedded directly within your app, perfect for local data storage.
To make working with SQLite easier in Objective-C, we'll use FMDB, a powerful and user-friendly wrapper. It simplifies common database tasks.
Why Choose FMDB?
While you can use SQLite's C API directly, FMDB offers several advantages:
- Object-Oriented: It provides Objective-C classes for database, result sets, and statements.
- Simplified API: Easier to write and read than raw C code.
- Parameter Binding: Safely handles arguments, preventing SQL injection.
- Thread Safety: Includes
FMDatabaseQueuefor safe multi-threaded access.
Setting Up FMDB
To use FMDB in your project, the easiest way is via CocoaPods. Add pod 'FMDB' to your Podfile and run pod install. After installation, remember to #import "FMDB.h" in your Objective-C files.
Alternatively, you can manually drag the FMDB source files into your project.
Opening Your Database
First, you need to create or open a database file. FMDB's FMDatabase class makes this straightforward. If the file doesn't exist, it will be created.
Try running this example to open a database:
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Get the path to the app's Documents directory
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
// Create an FMDatabase object
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) {
NSLog(@"Error: Could not open database.");
// Always check for errors!
return 1;
}
NSLog(@"Database opened successfully at: %@", dbPath);
// Close the database when done
[db close];
NSLog(@"Database closed.");
}
return 0;
}Creating a Table
Once the database is open, you can execute SQL commands like CREATE TABLE using executeUpdate:. This method is used for any SQL that doesn't return a result set (e.g., INSERT, UPDATE, DELETE).
Run this code to create a 'users' table:
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) { NSLog(@"Error opening db."); return 1; }
NSString *sql = @"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)";
BOOL success = [db executeUpdate:sql];
if (success) {
NSLog(@"Table 'users' created or already exists.");
} else {
NSLog(@"Error creating table: %@", [db lastErrorMessage]);
}
[db close];
}
return 0;
}Inserting Data
To add data to your table, use executeUpdate: again. FMDB is great at handling parameters, preventing SQL injection. Use ? as placeholders for your values.
See how we insert two users:
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) { NSLog(@"Error opening db."); return 1; }
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"];
BOOL success1 = [db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"Alice", @25];
BOOL success2 = [db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"Bob", @30];
if (success1 && success2) {
NSLog(@"Users inserted successfully!");
} else {
NSLog(@"Error inserting users: %@", [db lastErrorMessage]);
}
[db close];
}
return 0;
}Querying Data
To retrieve data, use executeQuery:. This returns an FMResultSet object, which you can iterate through to get your results. Each row's columns can be accessed by name or index.
Let's fetch the users we just added:
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) { NSLog(@"Error opening db."); return 1; }
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"];
[db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"Charlie", @28];
FMResultSet *rs = [db executeQuery:@"SELECT id, name, age FROM users"];
while ([rs next]) {
int userId = [rs intForColumn:@"id"];
NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
NSLog(@"User ID: %d, Name: %@, Age: %d", userId, name, age);
}
[rs close]; // Always close the result set
[db close];
}
return 0;
}Updating and Deleting Data
Modifying or removing records also uses executeUpdate:. Just provide the appropriate SQL UPDATE or DELETE statements, again using ? for parameters.
This example updates 'Charlie's age and then deletes 'Bob':
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) { NSLog(@"Error opening db."); return 1; }
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)"];
[db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"Charlie", @28];
[db executeUpdate:@"INSERT INTO users (name, age) VALUES (?, ?)", @"Bob", @30];
// Update Charlie's age
BOOL updateSuccess = [db executeUpdate:@"UPDATE users SET age = ? WHERE name = ?", @29, @"Charlie"];
if (updateSuccess) { NSLog(@"Charlie's age updated."); }
// Delete Bob
BOOL deleteSuccess = [db executeUpdate:@"DELETE FROM users WHERE name = ?", @"Bob"];
if (deleteSuccess) { NSLog(@"Bob deleted."); }
[db close];
}
return 0;
}Using Transactions for Reliability
For sequences of database operations that must all succeed or all fail, use transactions. FMDB provides beginTransaction, commit, and rollback methods to ensure data integrity.
If any operation within the transaction fails, you can roll back to the state before the transaction began.
#import <Foundation/Foundation.h>
#import "FMDB.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *docsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:@"myApp.sqlite"];
FMDatabase *db = [FMDatabase databaseWithPath:dbPath];
if (![db open]) { NSLog(@"Error opening db."); return 1; }
[db executeUpdate:@"CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY, name TEXT, price REAL)"];
[db beginTransaction];
BOOL success = YES;
if (![db executeUpdate:@"INSERT INTO products (name, price) VALUES (?, ?)", @"Apple", @1.0]) {
success = NO;
}
// Simulate a failure by trying to insert a bad value (e.g., duplicate PK if not autoinc)
// For this example, let's just make the second insert conditional
if (success && ![db executeUpdate:@"INSERT INTO products (name, price) VALUES (?, ?)", @"Orange", @1.5]) {
success = NO;
}
if (success) {
[db commit];
NSLog(@"Transaction committed: products inserted.");
} else {
[db rollback];
NSLog(@"Transaction rolled back due to error: %@", [db lastErrorMessage]);
}
[db close];
}
return 0;
}Check Your Understanding
Which of the following statements about using FMDB for SQLite in Objective-C are true?
Recap: SQLite & FMDB
Great job! You've learned how to integrate SQLite databases into your Objective-C apps using the FMDB wrapper.
- SQLite is a lightweight, embedded database.
- FMDB simplifies SQLite operations with an Objective-C API.
- You can open databases, create tables, and perform CRUD (Create, Read, Update, Delete) operations.
- Always use parameterized queries for safety and consider transactions for reliability.
This knowledge is crucial for managing local data storage in your legacy Objective-C applications!
よくある質問
「FMDBによるSQLite連携」レッスンは無料ですか?
はい。「FMDBによるSQLite連携」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Objective-C iOS Development for Legacy & Enterprise Appsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Objective-C iOS Development for Legacy & Enterprise Appsコースには全4レッスンが含まれています。
「FMDBによるSQLite連携」で何を学びますか?
広く使われているFMDBラッパーを利用して、Objective-CアプリにSQLiteデータベースを統合し、データを直接操作します。 ブラウザで直接実行するハンズオンコードでObjective-C iOS Development for Legacy & Enterprise Appsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Objective-C iOS Development for Legacy & Enterprise Appsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのObjective-C iOS Development for Legacy & Enterprise Appsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「FMDBによるSQLite連携」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このObjective-C iOS Development for Legacy & Enterprise Appsレッスンでコードを書いて実行できますか?
はい。すべてのObjective-C iOS Development for Legacy & Enterprise Appsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- プロパティリストとアーカイブ
- Core Dataの基礎
- FMDBによるSQLite連携
- NSUserDefaultsによる設定の保存