【Swift】GRDB数据库本地存储聊天记录

这篇具有很好参考价值的文章主要介绍了【Swift】GRDB数据库本地存储聊天记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  文章来源地址https://www.toymoban.com/news/detail-807425.html

//
//  DataManager.swift
//  GRDBDemo
//
//  Created by Apple on 2021/4/21.
//


import GRDB

struct DataBaseName {
    /// 数据库名字
    static let test = "conversation.db"
}

/// 数据库表名
struct TableName {
    
    static let message = "ChatMessage"
}

/// 数据库连接
class DBManager: NSObject {
    /// 数据库路径
    private static var dbPath: String = {
        // 获取工程内容数据库名字
        let filePath: String = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first!.appending("/\(DataBaseName.test)")
        
        //print("数据库地址:", filePath as Any)
        return filePath
    }()
    
    /// 数据库配置
    private static var configuration: Configuration = {
        // 配置
        var configuration = Configuration()
        // 设置超时
        configuration.busyMode = Database.BusyMode.timeout(5.0)
        // 试图访问锁着的数据
        //configuration.busyMode = Database.BusyMode.immediateError
        
        return configuration
    }()
    
    // MARK: 创建数据 多线程
    /// 数据库 用于多线程事务处理
    static var dbQueue: DatabaseQueue = {
        // 创建数据库
        let db = try! DatabaseQueue(path: DBManager.dbPath, configuration: DBManager.configuration)
        db.releaseMemory()
        // 设备版本
        return db
    }()
}
//
//  ChatMessage.swift
//  GRDBDemo
//
//  Created by Apple on 2021/4/21.
//

import Foundation
import GRDB

/// 聊天消息类
struct ChatMessage: Codable {
    
    var messageId : String?
    var messageType : String?
    var messageContent : String?
    var senderId : String?
    var targetId : String?
    
    private enum Columns: String, CodingKey, ColumnExpression {
        
        case messageId
        case messageType
        case messageContent
        case senderId
        case targetId
    }
}

extension ChatMessage: MutablePersistableRecord, FetchableRecord {
    /// 获取数据库对象
    private static let dbQueue: DatabaseQueue = DBManager.dbQueue
    
    //MARK: 创建
    /// 创建数据库
    private static func createTable() -> Void {
        try! self.dbQueue.inDatabase { (db) -> Void in
            // 判断是否存在数据库
            if try db.tableExists(TableName.message) {
                debugPrint("表已经存在")
                return
            }
            // 创建数据库表
            try db.create(table: TableName.message, temporary: false, ifNotExists: true, body: { (t) in
                t.column(Columns.messageId.rawValue, Database.ColumnType.text)
                t.column(Columns.messageType.rawValue, Database.ColumnType.text)
                t.column(Columns.messageContent.rawValue, Database.ColumnType.text)
                t.column(Columns.senderId.rawValue, Database.ColumnType.text)
                t.column(Columns.targetId.rawValue, Database.ColumnType.text)
            })
        }
    }
    
    //MARK: 插入
    /// 插入单个数据
    static func insert(message: ChatMessage) -> Void {
        // 判断是否存在
        guard ChatMessage.query(messageId: message.messageId!) == nil else {
            debugPrint("插入消息 内容重复")
            // 更新
            self.update(message: message)
            return
        }
        
        // 创建表
        self.createTable()
        // 事务
        try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in
            do {
                var messageTemp = message
                // 插入到数据库
                try messageTemp.insert(db)
                return Database.TransactionCompletion.commit
            } catch {
                return Database.TransactionCompletion.rollback
            }
        }
    }
    
    //MARK: 查询一条记录
    static func query(messageId: String) -> ChatMessage? {
        // 创建数据库
        self.createTable()
        // 返回查询结果
        return try! self.dbQueue.unsafeRead({ (db) -> ChatMessage? in
            return try ChatMessage.filter(Column(Columns.messageId.rawValue) == messageId).fetchOne(db)
        })
    }
    
    //MARK:查询与某人聊天的多条记录 - 从第几页开始
    static func query(userId:String,page:Int) -> [ChatMessage] {
        // 创建数据库
        self.createTable()
        
        return try! self.dbQueue.unsafeRead({ (db) -> [ChatMessage] in
            return try ChatMessage.fetchAll(db, sql: "Select * from ChatMessage where senderId = '\(userId)' or targetId = '\(userId)' limit \(20 * page),20")
        })
    }
    
    /// 查询所有
    static func queryAll() -> [ChatMessage] {
        // 创建数据库
        self.createTable()
        // 返回查询结果
        return try! self.dbQueue.unsafeRead({ (db) -> [ChatMessage] in
            return try ChatMessage.fetchAll(db)
        })
    }
    
    //MARK: 更新
    /// 更新
    static func update(message: ChatMessage) -> Void {
        /// 创建数据库表
        self.createTable()
        // 事务 更新场景
        try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in
            do {
                // 赋值
                try message.update(db)
                return Database.TransactionCompletion.commit
            } catch {
                return Database.TransactionCompletion.rollback
            }
        }
    }
    
    //MARK: 删除
    /// 根据messageId删除聊天记录
    static func delete(messageId: String) -> Void {
        // 查询
        guard let message = self.query(messageId: messageId) else {
            return
        }
        // 删除
        self.delete(message: message)
    }
    
    /// 删除单个聊天信息
    static func delete(message: ChatMessage) -> Void {
        // 是否有数据库表
        self.createTable()
        // 事务
        try! self.dbQueue.inTransaction { (db) -> Database.TransactionCompletion in
            do {
                // 删除数据
                try message.delete(db)
                return Database.TransactionCompletion.commit
            } catch {
                return Database.TransactionCompletion.rollback
            }
        }
    }
}

   使用示例:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
   
        let user1 = ChatMessage(messageId: "1010", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2")
        ChatMessage.insert(message: user1)
        
        let user2 = ChatMessage(messageId: "1012", messageType: "text", messageContent: "12345", senderId: "123", targetId: "2")
        ChatMessage.insert(message: user2)
        
        let user3 = ChatMessage(messageId: "1013", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123")
        ChatMessage.insert(message: user3)
        
        let user4 = ChatMessage(messageId: "1014", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2")
        ChatMessage.insert(message: user4)
        
        let user5 = ChatMessage(messageId: "1015", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123")
        ChatMessage.insert(message: user5)
        
        let user6 = ChatMessage(messageId: "1016", messageType: "text", messageContent: "12345", senderId: "123", targetId: "2")
        ChatMessage.insert(message: user6)
        
        let user7 = ChatMessage(messageId: "1017", messageType: "text", messageContent: "12345", senderId: "1", targetId: "2")
        ChatMessage.insert(message: user7)
        
        let user8 = ChatMessage(messageId: "1018", messageType: "text", messageContent: "12345", senderId: "1", targetId: "123")
        ChatMessage.insert(message: user8)
        
        let message1 = ChatMessage.query(userId: "123", page: 0)
        print(message1)

    }

 

  

到了这里,关于【Swift】GRDB数据库本地存储聊天记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android开发----实现登录注册页面(创建本地数据库,对注册的账户密码进行存储)

    写在前面: 本文实现了登录注册页面的开发,创建了本地数据库,存储注册的账户密码。注册账户为手机号,对账户为手机号进行了正则化验证。登录成功跳转至主页面。 20221028-实现登录注册功能 首先说一下,项目部署是在原有项目新建两个activity( 项目右键–new–activi

    2024年02月03日
    浏览(55)
  • 数据库系统-数据物理存储

    1.1.1 磁盘的结构特性 1.1.2 DBMS数据存储查询原理 记录:磁盘块 。OS的文件存储记录表(FAT)记录 数据 在哪些磁盘块当中block 数据先加载到内存缓冲区中,有一个内存页page block的对应表 磁盘块Block已经装载进了磁盘页Page,有一个 记录Record 记录所在内存位置Point的映射 记录:

    2023年04月20日
    浏览(35)
  • [Android Studio]Android 数据存储--SQLite数据库存储

     🟧🟨🟩🟦🟪 Android Debug 🟧🟨🟩🟦🟪 Topic   发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 💯实战演练--基于SQLite数据库的通讯录实现数据的增删改查 1,创建程序 2,放置界面控件 3,编写界面交互代码 4, 核心方法讲解 5,数据库

    2024年02月08日
    浏览(47)
  • 爬虫之数据库存储

    在对于爬取数量数量较少时,我们可以将爬虫数据保存于CSV文件或者其他格式的文件中,既简单又方便,但是如果需要存储的数据量大,又要频繁访问这些数据时,就应该考虑将数据保存到数据库中了。目前主流的数据库有关系性数据库MySQL,以及非关系性数据库MongoDB和Red

    2023年04月09日
    浏览(90)
  • 数据库: 存储过程

    sql server begin end用法: SQL Server中的BEGIN END用法是用于定义一个代码块,这个代码块可以包含多个SQL语句,BEGIN END通常用于控制流程语句,例如IF语句、WHILE语句、TRY CATCH语句等。在BEGIN END代码块中,可以使用变量、函数、存储过程等SQL Server的元素。BEGINEND的语法如下: BEGIN SQL语

    2024年02月09日
    浏览(41)
  • Python与数据库存储

    Python与数据库存储的最佳实践包括以下几个方面的内容: 连接数据库:使用合适的数据库连接库,如 sqlite3 、 psycopg2 、 pymysql 等来连接数据库。创建连接对象并通过该对象获取游标。 创建数据表:使用SQL语句在数据库中创建数据表。可以使用游标的 execute() 方法执行SQL语句

    2024年02月07日
    浏览(37)
  • MySQL 数据库存储引擎

    目录 一、存储引擎简介 二、MyISAM存储引擎 1、MylSAM介绍 2、MyISAM表支持3种不同的存储格式 3、MylSAM的特点 4、MyISAM使用的生产场景 三、InnoDB存储引擎 1、InnoDB介绍 2、InnoDB的特点 3、InnoDB适用生产场景 4、MyISAM和InnoDB的区别 四、查看和修改存储引擎 1、查看系统支持的存储引擎

    2023年04月25日
    浏览(58)
  • 数据库数据恢复-Syabse数据库存储页底层数据杂乱的数据恢复案例

    数据库恢复环境: Sybase版本:SQL Anywhere 8.0。 数据库故障: 数据库所在的设备意外断电后,数据库无法启动。 错误提示: 使用Sybase Central连接后报错:     数据库故障分析: 经过北亚企安数据恢复工程师检测,定位到数据库无法启动的原因:突然断电导致Sybase数据库无法正

    2024年02月15日
    浏览(45)
  • 【数据库】数据库的介绍、分类、作用和特点,AI人工智能数据如何存储

    欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是《数据库》系列文章,每篇文章将以博主理解的角度展开讲解, 特别是针对知识点的概念进行叙说,大部分文章将会对这些概念进行实际例子验证,以此达到加深对知识点的理解和掌握。 温馨提示:博主能力有限,理解水

    2024年04月14日
    浏览(75)
  • 【MySQL 数据库】9、存储过程

    🌱 存储过程是事先经过编译并存储在数据库中的 SQL 语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,可以提高数据处理效率 🌱 存储过程思想上很简单:就是数据库 SQL 语言层面的代码封装与重用 🍃 【封装,复用

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包