安装
1
| $ npm i egg-mysql --save
|
egg 的 MySQL 插件,支持egg 应用访问 MySQL 数据库。
本插件基于ali-rds,具体用法可以参考ali-rds文档。
更改${app_root}/config/plugin.js
以启用 MySQL 插件:
1 2 3 4
| exports.mysql = { enable: true, package: 'egg-mysql', };
|
配置数据库信息${app_root}/config/config.default.js
:
简单的数据库实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| exports.mysql = { // database configuration client: { // host host: 'localhost', // port port: '3306', // username user: 'test_user', // password password: 'test_password', // database database: 'test', }, // load into app, default is open app: true, // load into agent, default is close agent: false, };
|
用法:
1 2
| app.mysql.query(sql, values);
|
多数据库实例
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
| exports.mysql = { clients: { db1: { host: 'mysql.com', port: '3306', user: 'test_user', password: 'test_password', database: 'test', }, }, default: {
},
app: true, agent: false, };
|
用法:
1 2 3 4 5
| const client1 = app.mysql.get('db1'); client1.query(sql, values);
const client2 = app.mysql.get('db2'); client2.query(sql, values);
|
CRUD 用户指南
插入
1 2 3
| const result = yield app.mysql.insert('posts', { title: 'Hello World' }); const insertSuccess = result.affectedRows === 1;
|
读
1 2 3 4 5 6 7 8 9
| const post = yield app.mysql.get('posts', { id: 12 });
const results = yield app.mysql.select('posts',{ where: { status: 'draft' }, orders: [['created_at','desc'], ['id','desc']], limit: 10, offset: 0 });
|
更新
1 2 3 4 5 6 7 8 9
| const row = { id: 123, name: 'fengmk2', otherField: 'other field value', modifiedAt: app.mysql.literals.now, }; const result = yield app.mysql.update('posts', row); const updateSuccess = result.affectedRows === 1;
|
删除
1 2 3
| const result = yield app.mysql.delete('table-name', { name: 'fengmk2' });
|
交易
手动
- 优势:
beginTransaction
,commit
或者rollback
可以完全由开发者控制
- 缺点:手写代码较多,忘记捕捉错误或清理会导致严重的bug。
1 2 3 4 5 6 7 8 9 10 11
| const conn = yield app.mysql.beginTransaction();
try { yield conn.insert(table, row1); yield conn.update(table, row2); yield conn.commit(); } catch (err) {
yield conn.rollback(); 回滚调用不会抛出错误 throw err; }
|
自动控制:有作用域的事务
接口:
1
| *beginTransactionScope(scope, ctx)
|
scope
:一个generatorFunction,它将执行这个事务的所有sqls。
ctx
: 当前请求的上下文对象,它会确保即使在嵌套事务的情况下,一个请求中同时也只有一个活动事务。
优点:好用,就好像你的代码里没有事务一样。
缺点:所有交易都会成功或失败,无法精确控制
1 2 3 4 5 6 7
| const result = yield app.mysql.beginTransactionScope(function* (conn) { yield conn.insert(table, row1); yield conn.update(table, row2); return { success: true }; }, ctx);
|
进步
自定义SQL拼接
1
| const results = yield app.mysql.query('update posts set hits = (hits + ?) where id = ?', [1, postId]);
|
文字
如果要在 mysql 中调用文字或函数,可以使用Literal
.
内部文字
- NOW():数据库系统时间,可以通过
app.mysql.literals.now
.
1 2 3 4 5
| yield app.mysql.insert(table, { create_time: app.mysql.literals.now });
|
自定义文字
下面的demo展示了如何CONCAT(s1, ...sn)
在mysql中调用函数进行字符串拼接。
1 2 3 4 5 6 7 8 9
| const Literal = app.mysql.literals.Literal; const first = 'James'; const last = 'Bond'; yield app.mysql.insert(table, { id: 123, fullname: new Literal(`CONCAT("${first}", "${last}"`), });
|