本文基于上一篇博文(pomelo新建一个服务类型)的基础继续扩展。

需求:玩家购买物品后,将记录添加到数据库中以持久化保存数据。

准备工作

环境要求:已安装 MySQL 的 Windows 版本。

首先安装所需依赖库:

先安装依赖库
npm install mysql
npm install generic-pool

app 目录下新建 dao/mysql/ 目录,并在该目录下创建以下两个文件。

第一个文件 dao-pool.js,负责创建 MySQL 连接池:

新建文件dao-pool.js
var _poolModule = require('generic-pool');

/*
 * Create mysql connection pool.
 */
var createMysqlPool = function(app) {
	var mysqlConfig = app.get('mysql');
	return _poolModule.Pool({
		name: 'mysql',
		create: function(callback) {
			var mysql = require('mysql');
			var client = mysql.createConnection({
				host: mysqlConfig.host,
				user: mysqlConfig.user,
				password: mysqlConfig.password,
				database: mysqlConfig.database
			});
			callback(null, client);
		},
		destroy: function(client) {
			client.end();
		},
		max: 10,
		idleTimeoutMillis : 30000,
		log : false
	});
};

exports.createMysqlPool = createMysqlPool;

第二个文件 mysql.js,封装 CRUD 操作:

新建文件mysql.js
// mysql CRUD
var sqlclient = module.exports;

var _pool;

var NND = {};

/*
 * Init sql connection pool
 * @param {Object} app The app for the server.
 */
NND.init = function(app){
	_pool = require('./dao-pool').createMysqlPool(app);
};

/**
 * Excute sql statement
 * @param {String} sql Statement The sql need to excute.
 * @param {Object} args The args for the sql.
 * @param {fuction} cb Callback function.
 *
 */
NND.query = function(sql, args, cb){
	_pool.acquire(function(err, client) {
		if (!!err) {
			console.error('[sqlqueryErr] '+err.stack);
			return;
		}
		client.query(sql, args, function(err, res) {
			_pool.release(client);
			cb(err, res);
		});
	});
};

/**
 * Close connection pool.
 */
NND.shutdown = function(){
	_pool.destroyAllNow();
};

/**
 * init database
 */
sqlclient.init = function(app) {
	if (!!_pool){
		return sqlclient;
	} else {
		NND.init(app);
		sqlclient.insert = NND.query;
		sqlclient.update = NND.query;
		sqlclient.delete = NND.query;
		sqlclient.query = NND.query;
		return sqlclient;
	}
};

/**
 * shutdown database
 */
sqlclient.shutdown = function(app) {
	NND.shutdown(app);
};

接下来新建 MySQL 配置文件:

新建文件mysql.json
{
	"development": {
	  "host" : "127.0.0.1",
		"port" : "3306",
		"database" : "pomelo",
		"user" : "root",
		"password" : ""
	},

	"production" : {
	  "host" : "127.0.0.1",
		"port" : "3306",
		"database" : "pomelo",
		"user" : "root",
		"password" : ""
	}
}

至此,准备工作完毕。

集成到 app.js

app.js 中添加以下代码,加载配置并初始化数据库客户端:

app.loadConfig("mysql", app.getBase() + "/config/mysql.json"); // 添加配置
app.configure('production|development', "game", function () {
    var dbclient = require("./app/dao/mysql/mysql.js").init(app); // 初始化dbclient
    app.set("dbclient", dbclient);// dbclient 为外部数据库接口,app,get("dbclient") 来使用
})

修改购买接口

修改 gameHandler.js 中的 buyGoods 函数,在允许购买时将记录写入数据库:


handler.buyGoods=function(msg,session,next){
	var id=msg.id;
    var count = msg.count;

    ///////////////////////////////

	console.log("购买物品玩家 uid:" + session.uid);

    if (id == "100" && count == 1) {//验证购买条件

        //允许购买
        var sql = " insert into `goods` (`id`, `owner`) VALUES(?, ?)";

        var args = [id, session.uid];
        var dbclient = pomelo.app.get('dbclient');//获取全局mysql client

        console.log(dbclient);
        dbclient.query(sql, args, function (err, res) {//执行sql语句 函数insert和query等效

            console.log("......................");
            console.log(err + "            " + JSON.stringify(res));


            console.log("......................");
            if (err) { // 数据库操作失败
                next(null, { msg: "购买失败,服务器错误!", code: 200 });

            }
            else {//购买成功
                next(null, { msg: "购买物品:#活血丹 成功", code: 200 });

            }
        }

        );

	}else{ // 不允许购买
			next(null,{msg:"你的金币不足,购买失败",code:200});
	}
}

运行测试

运行测试后查看数据库,验证购买记录是否成功写入。

服务端日志: