现如今数据库的发展很快,犹如百花齐放
关系型数据库、NoSQL、图数据库、嵌入式数据库……层出不穷
虽然各自应用的场景不同
但无论如何,关系型数据库使用面最广,NoSQL人气最高
Dart SDK中并没有原生的数据库驱动
但是无论是PostgreSQL还是SQLite还是MongoDB,都能找到对于的包
看了一下Pub和Github
不得不说,对数据库支持最好还是PostgreSQL和MongoDB
接下来的几篇帖子会对常用数据库作简单演示
这里说一下MySQL
MySQL应用广泛,资料也很全
MySQL驱动做得比较好的应该是sqljocky
但是Pub中READMI.md的一句话着实让人、、、汗颜
It isn’t finished, but should work for most normal use.
好吧!只能说,正式应用需谨慎
注:
sqljocky只能运行在虚拟机中
不能在浏览器端运行
pubspec.yaml
1
2
3
4 1name: Note19
2dependencies:
3 sqljocky: "^0.14.1"
4
一般情况下我们并不会在程序中创建数据库
因为大多时候虚拟主机提供的都是固定的数据库
用户并没有创建的权限
另外,删除和新建数据库、表
可以用Drop、Create if not exists命令
如果要查询数据库或表是否存在,可以通过以下sql语句
1
2
3
4
5
6 1//查询数据库TempDB是否存在
2select count(*) from information_schema.tables where table_schema='tempdb';
3
4//查询数据库TempDB中是否存在Users表
5select count(*) from information_schema.tables where table_schema='tempdb' and table_name='users';
6
main.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 1import 'package:sqljocky/sqljocky.dart';
2import 'package:sqljocky/utils.dart';
3
4main() async {
5 /**
6 * 连接服务器,host默认'localhost',port默认3306
7 * 密码为空时,不设置password,数据库名称db可以省略
8 * 如果权限足够,连接服务器可以新建数据库
9 */
10 print("Opening connection");
11 var pool = new ConnectionPool(host: 'localhost', port:3306, user:'root');
12 await pool.query('drop database if exists TempDB');
13 await pool.query('create database TempDB');
14
15 /**
16 * 新建连接的时候,之前的连接资源并不会自动释放
17 * 需要调用closeConnectionsWhenNotInUse
18 * 或closeConnectionsNow
19 * 如果程序运行结束的时候,进程并没有退出
20 * 说明资源未及时释放
21 */
22 pool.closeConnectionsNow();
23
24 /**
25 * 新连接刚建的数据库
26 * 赋值给之前的pool变量
27 */
28 pool = new ConnectionPool(
29 host: 'localhost', port: 3306, user: 'root', db: 'TempDB');
30
31 /**
32 * 除了ConnectionPool.query
33 * 在'package:sqljocky/utils.dart'中
34 * utils提供了两个实用的类用来删除表和执行多条sql语句
35 */
36 print("Drop tables");
37 await new TableDropper(pool, ['users']).dropTables();
38
39 /**
40 * 也许是出于安全考虑,为了预防SQL攻击
41 * sqljocky并不支持单个字符串执行多条分号分隔的sql语句
42 * 如:"'insert into ...; insert into ..."
43 * 有可能你习惯拼接sql语句,但是
44 * 程序员不应该执行“删除地球”这样的SQL语句
45 * 而是写“删除一个行星”,然后将“地球”当作参数传入
46 * 也就是预处理
47 * 下面的代码仅仅是演示QueryRunner(ConnectionPool, List)的用法
48 * 适用于初始化数据库
49 */
50 print("Create tables");
51 await new QueryRunner(pool, [
52 'CREATE TABLE users ('
53 'name varchar(100) NOT NULL,'
54 'email varchar(100) NOT NULL)',
55 'INSERT INTO users(name, email) VALUES ("Wang","wang@qq.com")',
56 'INSERT INTO users(name, email) VALUES ("Li","li@163.com")'
57 ]).executeQueries();
58
59 /**
60 * 预处理
61 * 如果仅执行一次sql语句,可使用prepareExecute(sql, list)
62 * 如果需要执行多次sql语句,可使用executeMulti函数
63 * 再通过executeMulti(List<List>)传入参数
64 * 如果sql语句有返回值,可遍历Future<List<Results>>
65 */
66 print('Prepare insert multiLine sql');
67 var preSql = await pool.prepare(
68 "insert into users(name, email) values(?, ?)");
69 await preSql.executeMulti([
70 ['Chen', 'chen@sina.com'],
71 ['Yu', 'yu@gmail.com']
72 ]);
73
74 /**
75 * ConnectionPool也提供了执行sql语句的函数
76 * 如果sql语句有返回值,可遍历Future<Results>
77 */
78 print('Select users');
79 var results = await pool.query('select * from users');
80 results.forEach((row) {
81 print('Name: ${row[0]}, email: ${row[1]}');
82 });
83
84 /**
85 * 事务处理
86 * 下面的代码综合了事务处理和预处理
87 * 代码风格上,并没有用之前的await关键字
88 * 而是在then中注册回调函数,浓浓的Dart味道
89 * 这样省了不少临时变量的声明过程
90 *
91 * 需要说明的是
92 * sqljocky中不能通过query('start transaction')开启事务
93 * 同时,事务处理会保持连接,直到调用commit或者rollback
94 * 在提交或回滚事务的之后,不能再查询数据,否则会抛出错误
95 *
96 * commit和rollback并不会直接释放资源
97 * 需要在then函数中注册回调函数,调用close函数
98 * 否则,会进入阻塞状态
99 */
100 print('Transaction start');
101 pool.startTransaction().then((Transaction trans) {
102 trans.prepareExecute(
103 'update users set email=? where name=?',
104 ['yu@sohu.com', 'Yu']).then((_) {
105 trans.commit().then((_) {
106 print("Transaction end");
107 pool.closeConnectionsNow();
108 });
109 });
110 });
111
112 /**
113 * 释放资源
114 * 由于在上面事务处理的代码中,commit已经释放了资源
115 * 因此本句代码可以省略
116 */
117 pool.closeConnectionsWhenNotInUse();
118}
119
运行结果:
本文图片资料来源出自“Dart语言中文社区”,允许转载,转载时请务必以超链接形式标明文章原始出处