这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
egg+mysql
框架提供了 egg-mysql 插件来访问 MySQL 数据库。这个插件既可以访问普通的 MySQL 数据库,也可以访问基于 MySQL 协议的在线数据库服务。
1.连接mysql
安装mysql2,egg-mysql
npm i mysql2 egg-mysql
在plugin.js中打开egg-mysql插件
//配置mysql内容
exports.mysql = {
enable: true, // 开启
package: "egg-mysql", // 对应哪个包
};
在config.default.js配置连接mysql的参数(具体参见官方文档),以下配置够用即可
config.mysql = {
client: {
// host
host: "xxxxxxIP地址(本地127.0.0.1)",
// 端口号
port: "3306",
// 用户名
user: "root",
// 密码
password: "123456",
// 数据库名
database: "database1",
},
// 是否加载到 app 上,默认开启
app: true,
// 是否加载到 agent 上,默认关闭
agent: false,
};
这个时候this.app.mysql就能链接到mysql的对象了
2.使用egg操作mysql的方法
create
// 插入
const result = await this.app.mysql.insert('posts', { title: 'Hello World' }); // 在 post 表中,插入 title 为 Hello World 的记录
=> INSERT INTO `posts`(`title`) VALUES('Hello World');
read
查询某一个数据使用get,和下面说到的select区别是,不过你根据条件查出来有多少,都只会选择第一个
const post = await this.app.mysql.get('posts', { id: 12 });
=> SELECT * FROM `posts` WHERE `id` = 12 LIMIT 0, 1;
使用select查询,里面可以使用where条件,cloumns查询出来的表字段,order排序方式,limit,offet用于分页处理的数据量和偏移量
const results = await this.app.mysql.select('posts', { // 搜索 post 表
where: { status: 'draft', author: ['author1', 'author2'] }, // WHERE 条件
columns: ['author', 'title'], // 要查询的表字段
orders: [['created_at','desc'], ['id','desc']], // 排序方式
limit: 10, // 返回数据量
offset: 0, // 数据偏移量
});
=> SELECT `author`, `title` FROM `posts`
WHERE `status` = 'draft' AND `author` IN('author1','author2')
ORDER BY `created_at` DESC, `id` DESC LIMIT 0, 10;
update
更新很简单,根据主键查询出来需要更新的数据,然后将需要更新的数据进行表数据替换。默认主键是id,如果不是id需要多加一个参数手动指定一下主键。
// 修改数据,将会根据主键 ID 查找,并更新
const row = {
id: 123,
name: 'fengmk2',
otherField: 'other field value', // any other fields u want to update
modifiedAt: this.app.mysql.literals.now, // `now()` on db server
};
const result = await this.app.mysql.update('posts', row); // 更新 posts 表中的记录
=> UPDATE `posts` SET `name` = 'fengmk2', `modifiedAt` = NOW() WHERE id = 123 ;
delete
删除就直接使用delete配合表,查询条件进行操作进行了。
const result = await this.app.mysql.delete('posts', {
author: 'fengmk2',
});
=> DELETE FROM `posts` WHERE `author` = 'fengmk2';
3.直接执行sql语句(容易sql注入,正规项目不建议)
插件本身也支持拼接与直接执行 sql 语句。使用 query 可以执行合法的 sql 语句。
极其不建议开发者拼接 sql 语句,这样很容易引起 sql 注入!!
const postId = 1;
const results = await this.app.mysql.query('update posts set hits = (hits + ?) where id = ?', [1, postId]);
=> update posts set hits = (hits + 1) where id = 1;
4.事务处理
用于同时修改多张表,比如支付数据我可能要把购物车的商品表清除,支付数据表增加,但是支付失败后,要还原清除的购物车商品表,所以必须使用事务
手动控制
const conn = await app.mysql.beginTransaction(); // 初始化事务
try {
await conn.insert(table, row1); // 第一步操作
await conn.update(table, row2); // 第二步操作
await conn.commit(); // 提交事务
} catch (err) {
// error, rollback
await conn.rollback(); // 一定记得捕获异常后回滚事务!!
throw err;
}
自动控制(推荐)
const result = await app.mysql.beginTransactionScope(async conn => {
// don't commit or rollback by yourself
await conn.insert(table, row1);
await conn.update(table, row2);
return { success: true };
}, ctx); // ctx 是当前请求的上下文,如果是在 service 文件中,可以从 `this.ctx` 获取到
// if error throw on scope, will auto rollback
源码就没有演示这么多了,挺简单一步一步来
centos+redis
1.centos安装redis
1、安装redis
yum -y install redis
2、启动和添加启动项
systemctl start redis.service
systemctl enable redis.service // 开机自启动
3、查看进程是否已经启动
ps -ef | grep redis
4、修改配置文件
/etc/redis.conf
5、注释掉这行,重启外网访问 bind 127.0.0.1
6、这个时候egg连接还是有问题,因为无密码,无本地ip和外网ip映射,触发了protectmode保护模式。还要将配置文件的mode模式更改为yes
7、重启服务
systemctl restart redis.service
8、注意服务器开放外网防火墙6379端口,不然会超时
9、redis支持设置密码
$vim /etc/redis/redis.conf
requirepass xxxxxxxxxx // xxxxxxxxxx is your password
2.Egg连接Redis
npm install egg-redis --save
//plugin.js 打开插件
exports.redis = {
enable: true,
package: 'egg-redis',
};
//config.default.js 配置插件
config.redis = {
client: {
port: 6379, // Redis port
host: '127.0.0.1', // Redis host
password: '',
db: 0
}
}
配置多连接池,egg-redis提供了多连接池的功能,业务需求中如果需要配置多个redis服务器可以参考。
config.redis = {
clients: {
foo: {
port: 6379, // Redis port
host: '127.0.0.1', // Redis host
password: 'auth',
db: 0,
},
bar: {
port: 6379,
host: '127.0.0.1',
password: 'auth',
db: 1,
},
}
}
Egg.js+Redis的使用
简单使用,在业务上用途比如要做一个缓存一张试卷5分钟,用途退出去5分钟还可以缓存在服务器
// app/controller/home.js
module.exports = app => {
return class HomeController extends app.Controller {
async index() {
const { ctx, app } = this;
// set
await app.redis.set('foo', 'bar');
// get
ctx.body = await app.redis.get('foo');
}
};
};
更多redis的操作可以参照redis官网的api,我这边主要是做了简单的存取 参照网上进行封装成一个service,进行存取方法的控制,比原生的get,set更加完善一点。