SQLite with FMDB in Swift (P1)

by Hoang Anh Tuan
1.2K views
This entry is part [part not set] of 2 in the series Swift SQLite with FMDB

Đối với việc làm ứng dụng phần mềm, đa số đều phải sử dụng đến database. Core Data của Apple cung cấp là 1 trong những sự lựa chọn phổ biến đối với ứng dụng trên iphone.
Theo í kiến cá nhân thì Core Data thường được dùng cho các database được tạo ra trong quá trình sử dụng, còn trong trường hợp nếu bạn có 1 database có sẵn để đưa vào app thì sao? Khi đó thì cần đưa 1 database đã được nhập sẵn vào app. SQlite là 1 lựa chọn tốt Ở bài viết này, mình sẽ giới thiệu cách sử dụng SQLite trong swift bằng thư viện FMDB.

Nội dung bài viết

  • Giới thiệu về FMDB
  • Tạo đường dẫn cho 1 database
  • Khởi tạo 1 database
  • Tạo kết nối đến database
  • Thực hiện truy vấn

FMDB Library:

  • FMDB là 1 thư viện hỗ trợ truy vấn Sqlite và quản lí dữ liệu hiệu quả.
  • Giúp bạn xử lí việc open connection/ close connection đến DB.
  • Có thể dùng cho cả swift hoặc obj-C.
  • Dễ dàng và nhanh chóng để tích hợp vào 1 project.
  • Cách sử dụng tương đối đơn giản, cho phép người dùng tự viết câu truy vấn theo ý muốn.

Bài viết này tập trung vào việc sử dụng SQlite bằng thư viện FMDB, không hướng dẫn về phần cài đặt FMDB. Nếu bạn chưa biết về cách cài đặt thư viện, hãy xem thêm tại:

https://guides.cocoapods.org/using/using-cocoapods.html

Trong bài viết này, mình sẽ lấy 1 ví dụ về việc khởi tạo và viết các câu truy vấn đến 1 DB chứa các quyển sách.
Khởi tạo struct Book:

struct Book {
    let id: Int
    let name: String
    let author: String
    let price: Double
    
    func toString() {
        print("Book's info: id: \(id), name: \(name), author: \(author), price: \(price)")
    }
}

Tạo 1 class DatabaseManager để thực hiện việc truy vấn DB.
Khởi tạo 1 biến database kiểu FMDatabase – Sẽ dùng để truy cập và thực hiện truy vấn đến DB.

import Foundation
import FMDB

class DatabaseManager {
    static let shared = DatabaseManager()
    var database: FMDatabase!
}

Tạo đường dẫn để lưu DB:

Nếu chưa có 1 DB có sẵn, thì khi tạo 1 DB cần phải có đường dẫn để lưu DB. Khởi tạo 1 đường dẫn cho 1 database có tên bookDB như sau:

func getDatabasePath() -> String {
   let directoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
   let path = directoryPath.first!.appendingPathComponent("musicDB.db")
   print(path)
   return path.description
}

Sau khi print được ra đường dẫn, để xem database vừa tạo: Vào Finder, sử dụng tổ hợp phím Cmd + Shift + G, post đường dẫn vừa lấy được vào, Finder sẽ đưa đến database vừa tạo.

Trong trường hợp đã có 1 DB bookDB có sẵn và được kéo vào trong app, thì lấy đường dẫn như sau:

func getPathOfExistDB() -> String? {
   if let path = Bundle.main.path(forResource: "bookDB", ofType: ".db") {
       return path
   } 
   return nil
}

Khởi tạo 1 database

func createDatabase() {
    if database == nil {
        if !FileManager.default.fileExists(atPath: getDatabasePath()) {
            database = FMDatabase(path: getDatabasePath())
        }
    }
}

Nếu 1 DB chưa tồn tại, thì khởi tạo 1 DB mới tại 1 đường dẫn đơn giản bằng cách khởi tạo 1 object FMDatabase tại 1 đường dẫn.

Note: Việc check xem đã tồn tại 1 DB tại 1 path cụ thể trước khi khởi tạo rất quan trọng, bởi nếu ta path đó đã có sẵn 1 DB rồi thì DB đó sẽ bị hủy đi để khởi tạo 1 DB mới.

Tạo kết nối đến Database:

Note: Khi muốn truy suất đến DB thì phải mở 1 liên kết với DB, khi đã hoàn thành việc truy suất thì phải đóng liên kết lại.

  • Tạo liên kết tới DB:
database.open()
  • Đóng liên kết tới DB:
database.close()

2 hàm trên đều trả về giá trị Bool để biết việc mở/đóng liên kết có thành công hay không.
Ta có thể kết hợp việc tạo DB cùng với việc mở/đóng liên kết thành 1 hàm để tiện sử dụng:

func openDatabaseConnectionAtPath(path: String) -> Bool {
    if database == nil {
        if !FileManager.default.fileExists(atPath: path) { // don’t want to create the database file again and destroy the original database.
            database = FMDatabase(path: path)
        }
    }
        
    if database != nil {
        if database.open() {
            print("Open Success")
            return true
        }
    }
    print("Open failed")
    return false
}

Tạo 1 bảng trong DB:

Câu truy vấn tạo bảng:

Viết câu truy vấn tạo bảng trong FMDB như sau:

let query = "create table Book (id integer primary key autoincrement not null, name text not null, author text not null, price float not null default 0)"

Để chạy câu truy vấn:

database.executeUpdate(query, values: nil)

Câu lệnh executeUpdate(…) dùng để thực hiện những câu truy vấn tạo ra sự thay đổi đến DB.

  • Thuộc tính values của hàm executeUpdate sẽ được nói ở phần sau, ở đây tạm thời để nil.
  • Hàm thực hiện câu truy vấn tạo bảng:
func createBookTable() {
    if openDatabaseConnectionAtPath(path: getDatabasePath()) {
        let query = "create table Book id integer primary key autoincrement not null, name text not null, author text not null, price float not null default 0"
        do {
            try database.executeUpdate(query, values: nil)
        } catch let err {
            print("Execute query failed. error: \(err.localizedDescription)")
        }
    }
    database.close()
}

Hàm createBookTable ở trên sẽ tạo ra 1 DB nếu DB chưa tồn tại, còn nếu DB đã tồn tại rồi thì sẽ tạo liên kết, thực hiện truy vấn rồi đóng liên kết.
Thực hiện câu truy vấn createBookTable:

Kiểm tra kết quả:

Ở phần tiếp theo, sẽ nói về các câu truy vấn insert, delete,…

Series Navigation

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.