美文网首页
iOS数据存储通用配置

iOS数据存储通用配置

作者: lifeLL | 来源:发表于2018-03-27 17:10 被阅读0次
    //
    //  CacheManage.swift
    //  MMore
    //
    //  Created by life on 2017/4/17.
    //  Copyright © 2017年 TT. All rights reserved.
    //
    
    import UIKit
    import FMDB
    import HandyJSON
    //MARK:- 存储配置表
    public let serializationCache:String = "serializationCache"//存储序列化字段
    enum cacheTableName {//表名 :以对应数据库名开头
        case db_login
        case db_status
        case db_useinfo //单聊用户信息
    }
    
    class CacheManage: NSObject {
        var databasePath: String!
    //    var database: FMDatabase?
        var dataqueue:FMDatabaseQueue?
        //数据库名
        let sql_database = "db.sqlite"
        fileprivate var fileManager: FileManager = FileManager.default
        static let shared: CacheManage = CacheManage()
    
        override init() { //初始化
            let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]) as String
            databasePath = documentsDirectory.appending("/\(sql_database)")
            dataqueue = FMDatabaseQueue.init(path: databasePath)
        }
    
        //    @discardableResult init(sqlName: String) {//不用单例是因为需要提供建多个数据库 sql_database
        //        super.init()
        //        let documentsDirectory = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]) as String
        //        databasePath = documentsDirectory.appending("/\(sqlName)")
        //        //判断如果数据库存在则不用init
        //        if !fileManager.fileExists(atPath: databasePath) {
        //            dataqueue = FMDatabaseQueue.init(path: databasePath)
        //        }
        //    }
    }
    extension CacheManage{//表结构
        func getFieldDicWith(tableName:cacheTableName) -> Dictionary<String,String> {
            var dic = [String:String]()
            switch tableName {
            case cacheTableName.db_login:
                dic = [serializationCache:"BLOB","store_id":"TEXT","m_auth":"TEXT","user_name":"TEXT"]
            case cacheTableName.db_status:
                dic = ["aaaa":"TEXT","bbbb":"TEXT","cccc":"TEXT"]
            case cacheTableName.db_useinfo:
                dic = ["nickName":"TEXT","user_id":"TEXT","avator":"TEXT"]
            }
    
            return dic
        }
    }
    //MARK:- 按业务扩展对应方法
    extension CacheManage {//MARK:- 单聊用户信息
        func getUserInfoByIdHX(userid:String)->UseInfoModel?{
             let arr =  CacheManage.shared.queryDataWith(tableName: .db_useinfo, dataDic:["user_id":userid]) //都会返回一个数组,即使空数组
            if arr.count > 0 {
                //字典转模型
                let dic = arr[0] as! [String:Any]?//一个id对应一个数组元素,即字典
                let useInfoModel = JSONDeserializer<UseInfoModel>.deserializeFrom(dict: dic as NSDictionary?)
                return useInfoModel
            }else{
                return nil
            }
        }
        func saveUserInfoWith(userId:String,avatorUrl:String,nickName:String){
            var userInfoDic = [String:Any]()
            userInfoDic["nickName"] = nickName
            userInfoDic["user_id"] = userId
            userInfoDic["avator"] = avatorUrl
            CacheManage.shared.saveDataWith(tableName: .db_useinfo, dataDic: userInfoDic)
    
        }
    }
    
    
    //-----------------------------------------------------------------------------
    extension CacheManage{ //MARK:- 增删改查原始语句
    
        /// 创建表
        ///
        /// - Parameters:
        ///   - tableName: 表名
        ///   - fieldDic: 字段
        func creatTable(tableName:cacheTableName,fieldDic:Dictionary<String, String>?) {//创表
            //1.构造字符串字段
            func fieldStrWithDictionary(fieldDic:Dictionary<String, String>) -> String {
                //拼接查询语句
                let dicKey=Array(fieldDic.keys)
                var str:String = ""
                for temp in dicKey {
                    str += temp + " " + fieldDic[temp]! + " NOT NULL,"
                }
                //裁剪字符串
                let index = str.index(str.endIndex, offsetBy: -1)
                let fieldStr = str.substring(to: index)
                return fieldStr
            }
            //2.创表
            let fieldStr = fieldStrWithDictionary(fieldDic: fieldDic!)
            let sql = "CREATE TABLE IF NOT EXISTS \(tableName) (id integer PRIMARY KEY, \(fieldStr));"
            dataqueue?.inDatabase { (db:FMDatabase?) in
                if (db?.open())! {
                    if !(db?.executeStatements(sql))! {
                        print("Error: \(db?.lastErrorMessage())")
                    }
                }
            }
        }
    
        /// 新增数据
        ///
        /// - Parameters:
        ///   - tableName: 表名
        ///   - dataDic: 新增的数据
        func saveDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>) {//增
            //处理字符串
            func getFieldsWith(fieldDic:Dictionary<String, String>,Dic:Dictionary<String, Any>)->(String,String,Array<Any>){
                let fieldKeys=Array(fieldDic.keys)
                var keysStr:String = ""
                var flagStr:String = ""
                var valueArray:Array = [Any]()
                for temp in fieldKeys {
                    keysStr +=  temp + ","
                    flagStr += "?,"
                    valueArray.append(Dic[temp] ?? "")
                }
                let fieldStr = keysStr.subStringLastChar(originalStr: keysStr, num: -1)
                let flaggStr = flagStr.subStringLastChar(originalStr: flagStr, num: -1)
                return (fieldStr,flaggStr,valueArray)
            }
            var serialDic = [String:Any]()
            serialDic = dataDic
            //有序列号字段就序列号,没有就不处理
            if dataDic[serializationCache] != nil {
                let data = NSKeyedArchiver.archivedData(withRootObject: dataDic[serializationCache] ?? "" ) as Data
                serialDic[serializationCache] = data
            }
            //表不存在就创表
            let fieldDic = getFieldDicWith(tableName: tableName)
            creatTable(tableName: tableName, fieldDic: fieldDic)
            dataqueue?.inDatabase({ (db:FMDatabase?) in
                //添加新增语句
                let fieldTuples = getFieldsWith(fieldDic: fieldDic,Dic:serialDic)
                let insertSql = "INSERT INTO \(tableName)(\(fieldTuples.0)) VALUES (\(fieldTuples.1));"
                db?.executeUpdate(insertSql, withArgumentsIn: fieldTuples.2)//传的字段和表的字段要对应才插入成功
            })
        }
    
        /// 根据指定字段删除 or dic==nil 则删掉表
        ///
        /// - Parameters:
        ///   - tableName: 表名
        ///   - dic: 指定字段及值for字典形式
        func delectDataWith(tableName:cacheTableName,dic:Dictionary<String,Any>? = nil) {//删
    
            func getFieldsWith(fieldDic:Dictionary<String, String>)->(String){
                let fieldKeys=Array(fieldDic.keys)
                var keysStr:String = ""
                if fieldKeys.count == 1 {
                    keysStr += fieldKeys[0] + " = ? "
                }else{
                    for temp in fieldKeys {
                        keysStr +=  temp + " = ? and "
                    }
                    keysStr = keysStr.subStringLastChar(originalStr: keysStr, num: -4)//空格算一个字符
                }
                return keysStr
            }
    
            dataqueue?.inDatabase({ (db:FMDatabase?) in
                if dic == nil { //删表
                    let delectSql = "DELETE FROM \(tableName)"
                    db?.executeUpdate(delectSql, withArgumentsIn: nil)
                }else{
                    let fieldStringS = getFieldsWith(fieldDic: dic as! Dictionary<String, String>)
                    let delectSql = "DELETE FROM \(tableName) WHERE \(fieldStringS)"
                    db?.executeUpdate(delectSql, withArgumentsIn: Array(dic!.values))//这里的赋值有漏洞,存在不对应概率
                }
    
            })
        }
    
        /// 更新表格字段:根据whereDic更新dataDic
        ///
        /// - Parameters:
        ///   - tableName: 表名
        ///   - dataDic:   修改字段及值
        ///   - whereDic:  查询字段及值
        func updateDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>,whereDic:Dictionary<String, Any>){
    
            func subStr(Dic:Dictionary<String, Any>)->String{
                let Keys=Array(Dic.keys)
                var str = ""
                for temp in Keys {
                    str = temp + "=?,"
                }
                str = str.subStringLastChar(originalStr: str, num: -1)
                return str
            }
    
            dataqueue?.inDatabase({ (db:FMDatabase?) in
                let fieldStr = subStr(Dic: dataDic)
                let whereStr = subStr(Dic: whereDic)
    
                let qudateSQL = "UPDATE \(tableName) SET \(fieldStr) WHERE \(whereStr)"
                db?.executeUpdate(qudateSQL, withArgumentsIn: Array(dataDic.values) + Array(whereDic.values))
            })
        }
    
        /// 根据Dic的键值对查询表
        ///
        /// - Parameters:
        ///   - tableName: 表名
        ///   - Dic: 字段和值
        /// - Returns: 字典元素数组
        @discardableResult func queryDataWith(tableName:cacheTableName,dataDic:Dictionary<String, Any>) -> [Any?] {
            //1.
            func getFieldsWith(fieldDic:Dictionary<String, String>)->(String){
                let fieldKeys=Array(fieldDic.keys)
                var keysStr:String = ""
                if fieldKeys.count == 1 {
                    keysStr += fieldKeys[0] + " = ? "
                }else{
                    for temp in fieldKeys {
                        keysStr +=  temp + " = ? and "
                    }
                    keysStr = keysStr.subStringLastChar(originalStr: keysStr, num: -4)//空格算一个字符
                }
                return keysStr
            }
            //2.
            let queryStr = getFieldsWith(fieldDic: dataDic as! Dictionary<String, String>)
            var ArgumentDic = [String:Any]()
            var ArgumentArr = [Dictionary<String, Any>]()
            dataqueue?.inDatabase({ (db:FMDatabase?) in
                if (db?.tableExists(String(describing: tableName)))! {//判断表是否存在
                    let selectSQL = "SELECT * FROM \(tableName) WHERE \(queryStr)"
                    let rs = db?.executeQuery(selectSQL, withArgumentsIn: Array(dataDic.values))
                    let fieldDic =  self.getFieldDicWith(tableName: tableName)
    
                    while (rs?.next())! {
                        let Keys = Array(fieldDic.keys)//对应表的字段
                        for temp in Keys {
                            switch fieldDic[temp]! as String {
                            case "TEXT":
                                ArgumentDic[temp] = rs?.string(forColumn: temp)
                            case "BLOB":
                                let data = rs?.data(forColumn: temp)
                                ArgumentDic[temp] = NSKeyedUnarchiver.unarchiveObject(with: data! ) //反序列化
                            case "INTEGER":
                                ArgumentDic[temp] = rs?.int(forColumn: temp)
                            case "DATETIME":
                                ArgumentDic[temp] = rs?.date(forColumn: temp)
                            default:
                                ArgumentDic[temp] = rs?.object(forColumnName: temp)
                            }
                        }
                        ArgumentArr.append(ArgumentDic)
    
                    }
                }
            })
            return ArgumentArr
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:iOS数据存储通用配置

          本文链接:https://www.haomeiwen.com/subject/fzyscftx.html