当前位置: > > > Swift - SQLiteDB库新增的SQLTable功能详解(便于操作SQLite库)

Swift - SQLiteDB库新增的SQLTable功能详解(便于操作SQLite库)

SQLiteDB 是一个好用的第三方封装库,用于操作 SQLite 数据库。具体的配置和使用方法可以看我的另一篇文章:Swift - 操作SQLite数据库(引用SQLite3库)
这里主要讲解下最新版本中新增的 SQLTable.swift 本文代码已升级至Swift3

1,SQLTable是做什么用的?
有时我们从数据库中把数据查询出来以后,为了映射成实体类对象,需要遍历查询结果集,一个个给实体类对象赋值。
同样当实体对象属性修改后,如果想保存到数据库,又需要把对象属性取出来拼成一个SQL语句执行。
这样就比较麻烦。
SQLTable 的作用就是把让实体类继承 SQLTable,它就会自行将实体类跟数据库表作关联映射。只要操作实体类对象就可以直接进行数据的读取,修改,新增操作。 

2,SQLTable的原理
查看 SQLTable.swift 源码可以看出,其内部实现使用到了Swift的反射,通过遍历对象内的所有属性,从而自动拼接成相应的SQL语句来执行。 

3,SQLTable的使用
比如我们有一张联系人表:
users(
uid integer primary key,
uname varchar(20),
mobile varchar(20)
)

(1)首先创建一个联系人实体类,继承SQLTable
class User:SQLTable {
    var uid = -1
    var uname  = ""
    var mobile = ""
    
    //设置主键(如果主键字段名就是id的话,这个可以省去,不用覆盖)
    override func primaryKey() -> String {
        return "uid";
    }
    
    required convenience init(tableName:String) {
        self.init()
    }
}
实体类与数据表的关联:
看上面的实体类定义可以发现,我们并没有指定这个用户类对应的数据表的名字。其实 SQLTable 内部已经帮我们做了,将类名变成小写并在尾部添加 s 便是对应的表名。(如果是 y 结尾的则去掉 y,加 ies
比如:User 类对应的表是 usersSweetCandy 对应的表是 sweetcandies

(2)查询数据(可附带条件)
//查询出所有数据,按id升序排列(后面可以跟多个排序字段)
let data = User.rows(order:"uid ASC") as! [User]
for item in data {
    print("\(item.uid):\(item.uname):\(item.mobile)")
}

//查询出前两条数据(limit条件)
let data2 = User.rows(limit: 2) as! [User]

//查询出电话以1开头的所有用户(filter条件)
let data3 = User.rows(filter:"mobile like '1%'") as! [User]

//查询出电话以1开头的第一个用户(多条件:filter,order,limit)
let data4 = User.rows(filter:"mobile like '1%'",order:"uid ASC",limit:1) as! [User]

(3)保存数据
如果实体类主键在数据库找不到对应记录则为新增。否则便为修改。
let user1 = User()
user1.uname = "hangge.com"
user1.mobile = "123"
if user1.save().success {
    print("数据插入成功")
}

4,完整的样例代码
import UIKit

class ViewController: UIViewController {
    
    var db:SQLiteDB!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //获取数据库实例
        db = SQLiteDB.shared
        //打开数据库
        _ = db.openDB()
        //如果表还不存在则创建表
        _ = db.execute(sql: "create table if not exists users(uid integer primary key,uname varchar(20),mobile varchar(20))")
        //清空数据库
        _ = db.execute(sql: "delete from users")
        
        //插入三条数据
        print("------ 开始插入数据 ------")
        let user1 = User()
        user1.uname = "张三"
        user1.mobile = "123"
        if user1.save() > 0 {
            print("数据插入成功")
        }
        
        let user2 = User()
        user2.uname = "李四"
        user2.mobile = "456"
        if user2.save() > 0 {
            print("数据插入成功")
        }
        
        let user3 = User()
        user3.uname = "王五"
        user3.mobile = "110"
        if user3.save() > 0 {
            print("数据插入成功")
        }
        
        //查询出所有的用户(order条件:按id排序)
        print("\n------ 开始查询所有数据 ------")
        let data = User.rows(order:"uid ASC") as! [User]
        for item in data {
            print("\(item.uid):\(item.uname):\(item.mobile)")
        }
        
        //修改数据
        print("\n------ 修改第二条数据 ------")
        data[1].mobile = "hangge.com"
        if data[1].save() > 0  {
            print("数据修改成功")
        }
        
        //再次查询出所有的用户(order条件:按id排序)
        print("\n------ 再次查询所有数据 ------")
        let data2 = User.rows(order:"uid ASC") as! [User]
        for item in data2 {
            print("\(item.uid):\(item.uname):\(item.mobile)")
        }
        
        //查询出前两条数据(limit条件)
        print("\n------ 查询出前两条数据 ------")
        let data3 = User.rows(limit: 2) as! [User]
        for item in data3 {
            print("\(item.uid):\(item.uname):\(item.mobile)")
        }
        //查询出电话以1开头的所有用户(filter条件)
        print("\n------ 查询出电话以1开头的所有用户 ------")
        let data4 = User.rows(filter:"mobile like '1%'") as! [User]
        for item in data4 {
            print("\(item.uid):\(item.uname):\(item.mobile)")
        }
        
        //多条件(filter,order,limit)
        print("\n------ 查询出电话以1开头的第一个用户 ------")
        let data5 = User.rows(filter:"mobile like '1%'", order:"uid ASC", limit:1) as! [User]
        for item in data5 {
            print("\(item.uid):\(item.uname):\(item.mobile)")
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
    }
}


控制台输出如下:

源码下载:hangge_953.zip
评论2
  • 2楼
    2017-08-25 08:53
    dolphinNEUQ

    hangge,您好!我想向您请教一下,我开始手机APP时使用了SQLiteDB和SQLTable这两个库文件,但是想到后期数据库中表可能再增加一列元素,就是再增加一个属性,增加的方法是我直接在对应的表的类文件中新增一个变量比如(var passWord = "")这时候,会出现再发布就会有新旧两个版本的APP,如果用户下载新的APP,旧版的APP中的数据是否会丢失?我自己测试了一下,不会丢失,会在旧表的基础上再自动添加一列,但这样可能会有问题,可能是我没测到。我也将这两个库文件中的代码细细看了一遍,但是我还是不太了解或者说没有找到对应在旧表上自动添加一列元素的代码,所以想请教您一下,先谢谢您啦!

  • 1楼
    2017-04-13 09:22
    zhaohuikt

    能更新下3.1的写法嘛,现在新更新的sdk,会在以下这个步骤闪退

            db.execute(sql: "create table if not exists users(uid integer primary key,uname varchar(20),mobile varchar(20))")

    站长回复

    文章代码已更新,你可以再看下。