swift FMDB的简单使用


import Foundation

import FMDB

/*

 1.创建队列

 2.创建表格

 3.操作数据

 */


//缓存时间

private let MAXDBCACHETIME:TimeInterval  = -3 * 24 * 60 * 60


//这个不停创建影响性能

private let dateFormatter =DateFormatter()


class FZSQLLiteManager {

    

    //单例 private init()

    staticlet shared = FZSQLLiteManager()

    

    //创建数据库队列

    let queue:FMDatabaseQueue


    privateinit() {

        

        //s沙盒路径

        let dbname ="test.db"

        

        //拼接路径

        var path =NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask,true)[0]

        path = (path asNSString).appendingPathComponent(dbname)

        print(path)

        //创建队列

        queue =FMDatabaseQueue(path: path)

        

        //打开数据库,创建表格

        createTable()

        

        //注册通知,清除缓存

        NotificationCenter.default.addObserver(self, selector: #selector(clearFZSQLCache), name:NSNotification.Name.UIApplicationDidEnterBackground, object:nil)

    }

    

   @objc private func clearFZSQLCache() {

    

    

    let dateStr =dateString(interval: MAXDBCACHETIME)

    

    let sql ="DELETE FROM T_Status WHERE createTime < ?;"

    

    queue.inDatabase { (db)in

        

        if db?.executeUpdate(sql, withArgumentsIn: [dateStr]) ==true  {

        

        

            print("删除了\(String(describing: db?.changes()))")

        }

        

    }

    

    }

    

    func dateString(interval:TimeInterval) -> String {

        

        

        let date =Date(timeIntervalSinceNow: interval)

        

        dateFormatter.dateFormat ="yyyy-MM-dd HH:mm:ss"

        

        let dateStr =dateFormatter.string(from: date)

        

        print("\(date)----\(dateStr)")

        

        return dateStr

    }

    

}


//MARK: 操作数据

extension FZSQLLiteManager {

    

    //MARK: 更新/插入数据

    

    /*

      INSERT OR REPLACE... -->这是数据库特有的语句:主键是新的就插入,一样的会覆盖更新

     */

    

    func updateData(userId:String,dataArr: [[NSString:AnyObject]]) {

        

        //1.准备 SQL

        let sql ="INSERT OR REPLACE INTO T_Status (statusId, userId, status) VALUES (?, ?, ?);"


        //2. 执行 SQL 

        /*

          1. queue.inDatabase -- 单条操作

          2. queue.inTransaction(开启事务) --批量操作

         */

        queue.inTransaction { (db, rollback)in

            

            //遍历数组,插入数据

            for dicin dataArr {

                

                

                guardlet statusId = dic["statusId"]as? String,

                    let jsonData =try? JSONSerialization.data(withJSONObject: dic, options: [])

                    else{

                        

                        continue

                }

                

                //执行

                if db?.executeUpdate(sql, withArgumentsIn: [statusId,userId,jsonData]) ==true

                {

                    print("操作成功")

                    

                }else{

                    

                    print("操作失败")

                    

                    //回滚

                    rollback?.pointee =true

                    

                    break

                    

                }

            }

            

            //s沙盒路径

            let dbname ="test.db"

            

            //拼接路径

            var path =NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask,true)[0]

            path = (path asNSString).appendingPathComponent(dbname)

            

            

            

            let data =NSData(contentsOfFile: path)

            

            if data !=nil {

            

                //MARK: 写到电脑方便测试

                if (data!as NSData).write(toFile:"/Users/fuzhong/Desktop/test3.db", atomically:true) ==true {

                

                print("ccccc")

                }

                

                

                

            }

            

        }


    }

    

    //MARK: 查询数据结果

    func execSqlQueryData(sql:String) -> [[String:AnyObject]] {

        

        var resultArr = [[String:AnyObject]]()

        

        

        queue.inDatabase { (db)in

            

            guardlet res =  db?.executeQuery(sql, withArgumentsIn: [])

                else{

                return

            

            }

            

            //取数值

            while res.next() {

            

                //取列数

                let column = res.columnCount()

                

                //遍历

                for iin 0..<column {

                    

                    guardlet attributeName = res.columnName(for: i),

                        let attributeValue = res.object(forColumnIndex: i)

                        else{

                            continue

                    }


                    resultArr.append([attributeName: attributeValueas AnyObject])

                   //print("\(attributeName)---\(attributeValue)")

                }

            

            }

          

        }

        

        return resultArr

    }


    //MARK: 查询数据 --返回指定的条数(分页)

    

    /// 从数据库中查询

    ///

    /// - Parameters:

    ///   - userId: 当前用户

    ///   - since_id: 返回比since_id更大的ID

    ///   - max_id: 返回比max_id更小的ID

    /// - Returns: 结果

    func loadData(userId:String,since_id: Int, max_id: Int) -> [[String:AnyObject]] {

        

        // 1. 准备SQL

        var sql ="SELECT statusId, userId, status FROM T_Status \n"

        sql +="WHERE userId = \(userId) \n "

        

        // 上拉/下拉,都是针对同一个 id进行判断

        if since_id >0 {

            sql +="AND statusId > \(since_id) \n"

        } elseif max_id > 0 {

            sql +="AND statusId < \(max_id) \n"

        }

        

        /*

          1. ORDER BY statusId DESC: 根据statusId降序

          2. LIMIT 20 : 每次限制最多返回 20条数据

         */

        sql +="ORDER BY statusId DESC LIMIT 20;"

        

        print("SQL语句:\(sql)")

        

        //执行返回结果

        let array =execSqlQueryData(sql: sql)

        

        var results = [[String:AnyObject]]()

        

        

        for dictin array {

            

            // 反序列化

            guardlet jsonData = dict["status"]as? Data,

               let json =try? JSONSerialization.jsonObject(with: jsonData, options: [])as? [String:AnyObject]

                else {

                    continue

            }

            

            // 追加到数组

            results.append(json ?? [:])

        }

        

        return results

    }

    

}


private extensionFZSQLLiteManager {



    @objcfunc createTable() -> () {

        

        //创建数据表

        /*

         CREATE TABLE IF NOT EXISTS "T_Status" (

         "statusId" INTEGER NOT NULL,

         "userId" INTEGER NOT NULL,

         "status" TEXT,

         "createTime" TEXT DEFAULT (datetime('now', 'localtime')),

         PRIMARY KEY("statusId","userId")

         );

         */

        

        //1. sql

        

        guardlet path = Bundle.main.path(forResource:"status.sql", ofType: nil),

            let sqlStr =try? String(contentsOfFile: path)

            else {

            

                return

        }

        

       //2. 执行 sql --内部串行队列同步执行

        queue.inDatabase { (db)in

            

            if db?.executeStatements(sqlStr) ==true {

                

                print("创建成功")

                

            }else{

                print("创建失败")

                

            }

            

        }

        

        print("over")

        

    }

    

}


猜你喜欢

转载自blog.csdn.net/qq_24143647/article/details/72771940