0

0

使用 Swift 3.0 操作 MySQL 数据库

高洛峰

高洛峰

发布时间:2016-11-22 10:20:44

|

1913人浏览过

|

来源于php中文网

原创

开始

在这篇教程中,我们采用 ubuntu 16.04 系统和 mysql 5.7。mysql 5.7 引入了一系列的新特性。其中一个就是提供了更加高效的存储 json 数据的能力,同时提供了查询 json 数据内部的能力。稍后如果 mysql 5.7 成为了 ubuntu 16.04 上默认的 mysql 版本以后,我们将使用 ubuntu 16.04 作为我们的操作系统。

如果你还没有安装 Swift, 你可以使用 apt-get 方式来安装。参见这篇文章的说明安装。2016 年 9 月底,苹果也开始在 Ubuntu16.04 上编译 Swift 的镜像。请查看 Swift.org 获取更多的信息。

创建数据库

我们把数据库命名为 swift_test, 分配的用户是 swift, 密码是 swiftpass,如果你熟悉 MySQL,你应该知道需要执行 GRANT ALL ON swift_test.* 进行授权。
下面是这部分的命令:

# sudo mysql
...
mysql> create user swift;
Query OK, 0 rows affected (0.00 sec)

mysql> create database swift_test;
Query OK, 1 row affected (0.00 sec)

mysql> grant all on swift_test.* to 'swift'@'localhost' identified by 'swiftpass';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye

创建 Swift 包

现在开始正式进行编码,首先创建一个包:

# mkdir swift_mysql
# swift package init --type executable

编写 Package.swift 文件:

import PackageDescription

let package = Package(
    name: "swift_mysql",
    dependencies:[
      .Package(url:"https://github.com/vapor/mysql", majorVersion:1)
    ]
)

第二步,我们使用一些辅助的工具代码来生成一些随机的数据,填充到数据库中。在 Sources 目录下添加 utils.swift 文件并在里面添加以下内容:

import Glibc

class Random {
  static let initialize:Void = {
    srandom(UInt32(time(nil)))
    return ()
  }()
}

func randomString(ofLength length:Int) -> String {
  Random.initialize
  let charactersString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  let charactersArray:[Character] = Array(charactersString.characters)
  
  var string = ""
  for _ in 0.. Int {
  Random.initialize
  return Int(random() % 10000)
}

Vapor MySQL

接下来是真正的代码,我们的 main.swift 文件使用了 Vapor MySQL 模块。

连接数据库

添加以下代码到 Sources/main.swift 中:

import Glibc
import MySQL

var mysql:Database
do {
  mysql = try Database(host:"localhost",
                       user:"swift",
                       password:"swiftpass",
                       database:"swift_test")
  try mysql.execute("SELECT @@version")
} catch {
  print("Unable to connect to MySQL:  \(error)")
  exit(-1)
}

以上代码设置数据库并且处理 mysql。构造器 Database(host:String, user:String, password:String, database:String) 一目了然。
语句 try mysql.execute("SELECT @@version”) 是用来测试保证我们连接正确,并成功连接到了数据库。如果 do 代码块运行无错误,接下来就可以开始操作数据库了!

整型和字符串

所有对 MySQL 的调用都将通过 execute(_:String) 方法。需要注意的是该方法和一些抽象 API 的方法不同,比如 .create(table:String, ...) 或者 .insert(table:String, …。execute 获取原始的 SQL 语句并传给 MySQL 连接器。

do {
  try mysql.execute("DROP TABLE IF EXISTS foo")
  try mysql.execute("CREATE TABLE foo (bar INT(4), baz VARCHAR(16))")

  for i in 1...10 {
    let int    = randomInt()
    let string = randomString(ofLength:16)
    try mysql.execute("INSERT INTO foo VALUES (\(int), '\(string)')")
  }

  // Query
  let results = try mysql.execute("SELECT * FROM foo")
  for result in results {
    if let bar = result["bar"]?.int,
       let baz = result["baz"]?.string {
      print("\(bar)\t\(baz)")
    }
  }
} catch {
  print("Error:  \(error)")
  exit(-1)
}

查询结果也是使用的 execute(_:String) 方法。但是返回的结果是一个 [String:Node] 字典。字典的 key 对应着数据库的列名。

Node 类型是 Vapor 中的数据结构,用于转化为不同的类型。你可以从这里获取更多的信息。使用 Node 类型来表达 MySQL 可以方便的转换成对应的 Swift 类型。比如:let bar = result["bar"]?.int 给我们一个整型。

继续

接着我们来看一些更复杂的例子,比如创建一个表,包含了 MySQL 的 DATE, POINT 和 JSON 数据类型。我们的表名叫 samples。

do {
  try mysql.execute("DROP TABLE IF EXISTS samples")
  try mysql.execute("CREATE TABLE samples (id INT PRIMARY KEY AUTO_INCREMENT, created_at DATETIME, location POINT, reading JSON)")

  // ... Date
  // ... Point
  // ... Sample
  // ... Insert
  // ... Query
} catch {
  print("Error:  \(error)")
  exit(-1)
}

要插入一个日期到数据库中,需要正确的 SQL 语句:

明日B2C电子商务系统源码
明日B2C电子商务系统源码

对于典型的数据库管理系统,尤其是B2C电子商务网站这样数据流量比较大的网络管理系统,必须要满足使用方便、操作灵活等设计需求。

下载
// ... Date
let now              = Date()
let formatter        = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" // MySQL will accept this format
let created_at       = formatter.string(from:date)

接下来使用 Swift 元组来创建一个 POINT:

// ... Point
let location = (37.20262, -112.98785) // latitude, longitude

最后,我们来处理 MySQL 5.7 中新的 JSON 数据类型,此外我们使用了 Jay 包来快速将一个 Swift 字典 [String:Any] 转换为 JSON 格式的字符串。

// ... Sample
  let sample:[String:Any] = [
    "heading":90,
    "gps":[
      "latitude":37.20262,
      "longitude":-112.98785
    ],
    "speed":82,
    "temperature":200
  ]

提示:你不需要显式在 Package.swift 中声明对 Jay 的依赖,因为在 MySQL 的包中已经包含了这个依赖。接下来我们把 JSON 数据转换为 String,用来拼凑 MySQL 语句。

let sampleData = try Jay(formatting:.minified).dataFromJson(any:sample) // [UInt8]
let sampleJSON = String(data:Data(sampleData), encoding:.utf8)

这样我们就有了 date, point 和 JSON 字符串(sample) 了, 现在添加数据到 sample 表中:

// ... Insert
let stmt = "INSERT INTO samples (created_at, location, sample) VALUES ('\(created_at)', POINT\(point), '\(sampleJSON)')"
try mysql.execute(stmt)

请注意我们在处理 POINT 时候,使用了一些技巧。在对 (point) 展开为字符串 (37.20262, -112.98785) 后,完整的字符串是 POINT(37.20262, -112.98785),这是 MySQL 所需要的数据,整个语句的字符串如下:

INSERT INTO samples (created_at, location, sample) VALUES ('2016-09-21 22:28:44', POINT(37.202620000000003, -112.98784999999999), '{"gps":{"latitude":37.20262,"longitude":-112.98785},"heading":90,"speed":82,"temperature":200}')

获取结果

警告:在写这篇文章的时候(2016-09-22), Vapor MySQL 1.0.0 有一个 bug:在读取 POINT 数据类型时会 crash 掉,所以不得不在下面代码中加入 do 代码块,然后不使用 select 语句。我们在 Vapor MySQL 中记录了这个 issue,等这个 issue 修复以后,我们将更新文章。

在下面的例子中,我们将使用 MySQL 5.7 中引入对 JSON 数据内部的查询特性,使用 SELECT … WHERE 查询 JSON 数据。在这里查询的是 samples 表中 JSON 数据类型 sample中、speed 字段大于 80 的数据。

// ... 查询
  let results = try mysql.execute("SELECT created_at,sample FROM samples where JSON_EXTRACT(sample, '$.speed') > 80") 
  for result in results {
    if let sample      = result["sample"]?.object,
       let speed       = sample["speed"]?.int,
       let temperature = sample["temperature"]?.int,
       let created_at  = result["created_at"]?.string {
      print("Time:\(created_at)\tSpeed:\(speed)\tTemperature:\(temperature)")
    }
  }

这里做一些说明。JSON_EXTRACT 函数是用来 返回从 JSON 文档中的数据,根据传入的路径参数选择文档中满足条件的数据。在本例中,我们解包了列 sample 中的 speed 值。

为了循环处理结果,我们使用了 for result in results 语句,接着使用 if let 语句验证结果数据。首先使用 let sample = result["sample"]?.object 获取一个字典,对应 MySQL 中的 JSON 文档,这是一句关键的代码!Vapor MySQL 库并没有返回一个 String,而 String 还需进行 JSON 的解析。这个解析工作库已经帮你做了,所以你可以直接使用 sample 字典啦。

剩下的 let 语句给了我们 speed,temperature 和 created_at。注意 created_at 在 MySQL 中是 DATETIME 类型,我们读取它为字符串。为了在 Swift 中转换成 Date 类型,需要使用 .date(from:String) 方法加一个 DateFormatter 来做类型转换。

获取代码

如果你想直接运行代码,请到 github 上下载我们的代码。
在任何地方使用 swift build 进行编译,运行可执行代码,不要忘了你还需要拥有一个数据库,用户名并且授权通过。

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

36

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

102

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

49

2026.02.03

c语言中/相关合集
c语言中/相关合集

本专题整合了c语言中/的用法、含义解释。阅读专题下面的文章了解更多详细内容。

9

2026.02.03

漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题
漫蛙漫画网页版入口与正版在线阅读 漫蛙MANWA官网访问专题

本专题围绕漫蛙漫画(Manwa / Manwa2)官网网页版入口进行整理,涵盖漫蛙漫画官方主页访问方式、网页版在线阅读入口、台版正版漫画浏览说明及基础使用指引,帮助用户快速进入漫蛙漫画官网,稳定在线阅读正版漫画内容,避免误入非官方页面。

76

2026.02.03

Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口
Yandex官网入口与俄罗斯搜索引擎访问指南 Yandex中文登录与网页版入口

本专题汇总了俄罗斯知名搜索引擎 Yandex 的官网入口、免登录访问地址、中文登录方法与网页版使用指南,帮助用户稳定访问 Yandex 官网,并提供一站式入口汇总。无论是登录入口还是在线搜索,用户都能快速获取最新稳定的访问链接与使用指南。

417

2026.02.03

Java 设计模式与重构实践
Java 设计模式与重构实践

本专题专注讲解 Java 中常用的设计模式,包括单例模式、工厂模式、观察者模式、策略模式等,并结合代码重构实践,帮助学习者掌握 如何运用设计模式优化代码结构,提高代码的可读性、可维护性和扩展性。通过具体示例,展示设计模式如何解决实际开发中的复杂问题。

4

2026.02.03

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

5

2026.02.03

Python 强化学习与深度Q网络(DQN)
Python 强化学习与深度Q网络(DQN)

本专题深入讲解 Python 在强化学习(Reinforcement Learning)中的应用,重点介绍 深度Q网络(DQN) 及其实现方法,涵盖 Q-learning 算法、深度学习与神经网络的结合、环境模拟与奖励机制设计、探索与利用的平衡等。通过构建一个简单的游戏AI,帮助学习者掌握 如何使用 Python 训练智能体在动态环境中作出决策。

4

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.1万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 821人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号