iOS-Swift 数据库 WCDB 二次封装使用/自定义字段映射类型

news2024/11/22 13:40:09

WCDB官方使用文档

WCDB简介

WCDB 是一个易用、高效、完整的移动数据库框架,它基于 SQLite 和 SQLCipher 开发,在微信中应用广泛,且支持在 C++、Java、Kotlin、Swift、Objc 五种语言环境中使用。

整体架构:
请添加图片描述

对于WCDB详细的介绍和使用请移步官方文档,本篇文章主要是对WCDB 常用的功能进行二次封装,使数据库的操作更方便一些。还有就是对于自定义映射类型的详细使用,作为官方文档在这块的一个补充。

安装
其它方式安装

通过 Cocoapods 安装

    pod 'WCDB.swift'

二次封装

DBmanager

import Foundation
import WCDBSwift

struct WcdbDataPath {
    static let basePath =  NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! + "/DB/wcdb.db"
}

//表名
enum DBTableName : String {
    case userTable = "userTable"
}

class DBmanager{
    static let share = DBmanager.init()
    var db: Database?
    init() {
        db = createDB()
        createTable()
    }
    
    private func createDB() -> Database {
        return Database(at: WcdbDataPath.basePath)
    }
    
    /// 数据库与表的初始化
    private func createTable() {
        do {
            //1. 创建主数据库main的相关表
            try db?.run(transaction: { _ in
                self.createTable(table: DBTableName.userTable, modelType: UserModel.self)
            })
            
        } catch let error {
            debugPrint("初始化数据库及ORM对应关系建立失败\(error.localizedDescription)")
        }
    }
    
    
    ///创建表
    private func createTable<T: TableDecodable>(table: DBTableName, modelType: T.Type) {
        do {
            try db?.create(table: table.rawValue, of: modelType)
        }catch let error {
            debugPrint(error.localizedDescription)
        }
    }
    
    ///插入数据
    public func inser<T: TableEncodable>(objects:[T], intoTable table: DBTableName){
        do {
            try db?.insert(objects, intoTable: table.rawValue)
        }catch let error {
            debugPrint(error.localizedDescription)
        }
    }
    
    ///修改
    public func update<T: TableEncodable>(fromTable table: DBTableName, on propertys:[PropertyConvertible], itemModel object:T,where condition: Condition? = nil){
        do {
            try db?.update(table: table.rawValue, on: propertys, with: object, where: condition)
        } catch let error {
            debugPrint(" update obj error \(error.localizedDescription)")
        }
    }
    
    ///删除
    public func deleteFromDb(fromTable table: DBTableName, where condition: Condition? = nil){
        do {
            try db?.delete(fromTable: table.rawValue, where:condition)
        } catch let error {
            debugPrint("delete error \(error.localizedDescription)")
        }
    }
    
    ///查询
    public func qurey<T: TableDecodable>(fromTable table: DBTableName, where condition: Condition? = nil, orderBy orderList:[OrderBy]? = nil) -> [T]? {
        do {
            let allObjects: [T] = try (db?.getObjects(fromTable: table.rawValue, where:condition, orderBy:orderList))!
            debugPrint("\(allObjects)");
            return allObjects
        } catch let error {
            debugPrint("no data find \(error.localizedDescription)")
        }
        return nil
    }
    
    ///删除数据表
    func dropTable(table: DBTableName) -> Void {
        do {
            try db?.drop(table: table.rawValue)
        } catch let error {
            debugPrint("drop table error \(error)")
        }
    }
    
    /// 删除所有与该数据库相关的文件
    func removeDbFile() -> Void {
        do {
            try db?.close(onClosed: {
                try self.db?.removeFiles()
            })
        } catch let error {
            debugPrint("not close db \(error)")
        }
    }
}

使用

新建一张表

  1. 在枚举中新增表名
//表名
enum DBTableName : String {
    case userTable = "userTable"
}
  1. 新建model
    示例model
import Foundation
import WCDBSwift

final class UserModel: TableCodable {
 
    var id: Int = 0
    var name: String = ""
    var height: Double = 0.0
      
    enum CodingKeys: String, CodingTableKey {
        typealias Root = UserModel
        static let objectRelationalMapping = TableBinding(CodingKeys.self)
        case id
        case name
        case height
    }
    
}
  1. 新建表
    在这里插入图片描述

数据库操作

首先创建数据库对象

  let commonDB = DBmanager.share

新增

      let model = UserModel()
        model.id = 1
        model.name = "张三"

commonDB.inser(objects: [model], intoTable: .userTable)

删除

 commonDB.deleteFromDb(fromTable: .userTable, where: UserModel.Properties.id.is(model.id))

修改

// 创建要更新的 UserModel 对象
var userToUpdate = UserModel()
userToUpdate.name = "NewName"
userToUpdate.height = 180.0

// 定义要更新的属性
let propertiesToUpdate = [UserModel.Properties.name, UserModel.Properties.height]

// 构建条件(例如,根据 id 更新)
let updateCondition = UserModel.Properties.id == 1

// 调用 update 方法
commonDB.update(fromTable: .userTable, on: [UserModel.Properties.height], itemModel: userToUpdate,where: updateCondition)

查询

if let tempArray:[UserModel] = commonDB.qurey(fromTable: .userTable) {
            userArray = tempArray
        }

自定义字段映射类型

自定义字段映射类型文档

示例

import Foundation
import WCDBSwift

final class UserModel: TableCodable {
 
    var id: Int = 0
    var name: String = ""
    var height: Double = 0.0
    var address: addressModel?
    
    enum CodingKeys: String, CodingTableKey {
        typealias Root = UserModel
        static let objectRelationalMapping = TableBinding(CodingKeys.self)
        case id
        case name
        case height
        case address
    }
    
}

//自定义字段映射类型
class addressModel: ColumnCodable {
    
    required init() {}
    
    var home:String = ""
    var company:String = ""

    static var columnType: ColumnType {
           return .BLOB
       }
    
    required init?(with value: WCDBSwift.Value) {
        let data = value.dataValue
        guard data.count > 0,
              let jsonDict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
            return nil
        }
        
        guard let home = jsonDict["home"] as? String else {
            return nil
        }
        guard let company = jsonDict["company"] as? String else {
            return nil
        }
        
        self.home = home
        self.company = company
    }
    
    func archivedValue() -> WCDBSwift.Value {
        var jsonDict: [String: Any] = [:]
        jsonDict["home"] = home
        jsonDict["company"] = company
        guard let data = try? JSONSerialization.data(withJSONObject: (jsonDict as NSDictionary), options: []) else {
            return FundamentalValue.init()
        }
        
        return FundamentalValue.init(data)
    }
    
}

结语

以上便是WCDB Swift 版本的基本使用,本篇旨在帮你快速的上手使用WCDB来完成数据库的基础操作。如需其它高级的数据库操作,请移步到官方文档。

WCDB仓库地址
WCDB官方文档直通车


感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tomcat安装教程

Tomcat官方网站&#xff1a;http://tomcat.apache.org/ 1.找到左边一栏有个Download&#xff0c;点击Tomcat 10 注意&#xff1a;Tomcat也是要下载JDK环境的&#xff0c;这里我使用Tomcat 10&#xff0c;JDK环境要大于等于11版本&#xff0c;具体可看下图&#xff1a; 2.下拉找…

更小、更安全、更透明:Google发布的Gemma推动负责任AI的进步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Python习题 101:输入年月打印日历

使用了 Python 的内置库 calendar&#xff0c;它提供提供与日历有关功能&#xff0c;可以帮助我们做时间日期相关的计算&#xff0c;省去复杂的判断&#xff0c;比较实用。

cv2读取中文路径图像名称

1.cv2.imdecode 是 OpenCV 库中的一个函数&#xff0c;用于从内存中的数据解码图像。这通常用于从文件、网络传输或数据库中读取图像数据而不必直接从磁盘读取。此函数特别适用于处理字节数组形式的图像数据。 img cv2.imdecode(buf, flagsNone) 参数说明&#xff1a; buf&am…

解锁PDF编辑新境界:2024年大家都在用的4款工具

PDF这个文件格式大家应该都不陌生吧。他以不易窜改和可以保持版式一直的优势成为我们日常传输文件的首选格式。随着使用使用率的增加&#xff0c;一些PDF表格如果能直接修改内容就能有效的提升工作效率。这就需要借助一些PDF编辑工具来实现啦。 1.福昕PDF编辑器 直达链接&am…

游戏(河南萌新2024)

1.超时的写法&#xff08;没有用堆优化&#xff09; #include <bits/stdc.h>using namespace std; typedef long long ll; typedef double db; typedef long double ldb; typedef pair<int, int> pii; typedef pair<ll, ll> PII; #define pb emplace_back /…

vulnhub靶场serial-php渗透(蜥蜴细!)

目录 一、信息收集 1.探测主机存活&#xff08;目标主机IP地址&#xff09; 2.访问web服务 3.后台目录和端口扫描 4.解析bak.zip源码 二、漏洞利用 1.构造payload 2.通过bp的repeater模块 3.get shell 4.获取反弹shell 三、提升权限 1. 查看系统版本&#xff0c;内核…

ctfshow 大赛原题 web697--web700

web697 先扫一下&#xff0c;其实也可以不用扫 因为什么也扫不出来 这里看到有一个参数 尝试一下数组 随便输了&#xff0c;出了验证回显抓个包看 ffifdyop e58 4611686052576742364这三个md5加密可以自带引号 SELECT master FROM secret WHERE password binary ,b…

文件包含漏洞汇总

文章目录 原理文件包含函数伪协议函数本地包含file协议filter协议input协议data协议 远程文件包含条件http协议 日志文件绕过概念日志路径复现 文件包含之条件竞争概念靶场介绍复现 文件下载文件下载常见的目录系统目录linuxwindows 程序配置文件apachenginxredis 目录遍历与目…

【STL专题】深入探索vector:动态数组的魔力【入门指南】

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;深入探索vector&#xff1a;动态数组的魔力&#xff0c;入门指南 &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | L…

结构体指针数组函数综合应用改写选票系统

第一次写百行的代码 有点吃不消 感受到程序员的不容易 其中遇到了很多问题 希望分享给大家 下面是是完整的且完善的代码 #include<stdio.h> #include<string.h> #include <stdlib.h> //定义结构体 struct XuanMin {char name[32];int tickets; }; //指针函…

1-4章节复习总结

1-4章节总结 章节重点回顾-第一章-中央处理单元练习题 章节重点回顾-第一章-进制章节重点回顾-第一章-校验码奇偶校验码CRC循环冗余校验码海明码练习题 多草节重点回顾-第一草-计算机体系结构分类章节重点回顾-第一章-计算机指令练习题 章节重点回顾-第一章-指令流水线练习题 章…

​​​​​Tomcat部署及优化

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

洞见新能源汽车产业更智能的未来

新能源汽车行业进入智能化时代&#xff0c;除了备受关注的无人驾驶领域&#xff0c;新能源汽车在智能化的进程逐渐加快。智能化已成为中国汽车品牌的竞争力。 作为专业提供算网的服务商之一&#xff0c;VERYCLOUD睿鸿股份跟随新能源汽车行业快速变化&#xff0c;受邀前往CIAS 2…

天环公益首次推出原创开发进度网站,配备后台管理系统

天环公益组织近期创新性地发布了一个专用于监控与展示项目开发进程的官方网站&#xff0c;该网站特色在于其自研的后台管理系统。 对于有兴趣深入了解或参与管理的用户&#xff0c;可直接访问后台页面&#xff0c;入口为&#xff1a;admin.php。 值得注意的是&#xff0c;当前…

教育教学质量评测系统开发之软件技术分析

开发教学质量评测系统它不仅能够有效提升教育管理的科学性与透明度&#xff0c;还能精准反映教学过程中的问题与亮点&#xff0c;为教育决策提供坚实的数据支持。通过该系统&#xff0c;学校能够全面、客观地收集学生、教师及家长的反馈意见&#xff0c;促进教学相长&#xff0…

java各种锁有什么区别

Java 虚拟机&#xff08;JVM&#xff09;中有几种不同类型的锁&#xff0c;每种锁都有其特定的用途和性能特点。下面我将为你介绍几种常见的锁&#xff1a; 1.独占锁&#xff08;也称为悲观锁&#xff09;&#xff1a; 1.synchronized&#xff1a;这是 Java 提供的一种内置的独…

【数据结构】——栈和队列的实现(赋源码)

在前面我们已经学过顺序表以及单链表、双向表链的实现都是一种线性表&#xff0c;这里可以我们介绍栈和队列——是具有特殊化的线性表 栈 栈的概念以及结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进⾏插入和删除元素操作。进⾏数据插⼊和删除操作的…