Node-MyBatis: A JavaScript Full‑Stack Data Persistence Solution for the Wukong Activity Platform

The article describes how the Wukong Activity Platform’s data‑persistence layer uses Node.js as a BFF with MySQL, combines raw drivers, optional ORMs, and a custom lightweight Node‑MyBatis framework that offers dynamic SQL templating, built‑in injection protection, declarative transaction decorators, and automatic TypeScript type generation for full‑stack JavaScript development.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Node-MyBatis: A JavaScript Full‑Stack Data Persistence Solution for the Wukong Activity Platform

The article introduces the technical architecture of the Wukong Activity Platform, focusing on the data‑persistence layer built with JavaScript/Node.js. It explains why the platform adopts Node as the BFF (Backend‑For‑Frontend) to achieve full‑stack JavaScript development and outlines the benefits such as tighter front‑back integration, reduced communication overhead, and a unified development perspective.

For data storage, MySQL is chosen as the relational database. The article first demonstrates the use of the pure MySQL driver in Node:

npm install mysql # install the driver
var mysql = require('mysql');
var connection = mysql.createConnection({
  host: '..', // db host
  user: '..', // db user
  password: '', // db password
  database: '..' // which database
});
connection.connect();
connection.query('SELECT id, name, rank FROM languages', function (error, results, fields) {
  if (error) throw error;
  console.log('The language rank is: ', results);
});
connection.end();

In real projects the driver is usually wrapped with a connection pool, promises/async‑await, and higher‑level transaction handling.

The article then reviews mainstream ORM solutions. It describes Sequelize (a Promise‑based Node.js ORM) with a model definition example:

// Define ORM model mapping
const Language = sequelize.define('language', {
  id: { type: DataTypes.INTEGER, primaryKey: true },
  name: { type: DataTypes.STRING },
  range: { type: DataTypes.INTEGER }
}, { timestamps: false });
const languages = await Language.findAll();

It also mentions TypeORM, which leverages TypeScript’s type system and supports both Active‑Record and Data‑Mapper patterns.

After evaluating ORM pros and cons (fast for simple CRUD, but limited for complex queries, learning curve, possible N+1 problems), the authors turn to MyBatis, a semi‑automatic ORM from the Java ecosystem, as a reference for building a custom solution in Node.

Node‑MyBatis is introduced with the following key features:

Simple and lightweight implementation without third‑party dependencies.

Flexible SQL templating using # (escaped placeholder) and $ (raw placeholder) expressions.

Support for dynamic SQL blocks via <% … %> (similar to EJS).

Built‑in SQL injection protection by escaping parameters.

Declarative transaction management using decorators.

TypeScript type generation from database metadata.

Example of a dynamic SQL template using the # expression:

SELECT id, book_name AS bookName, publish_time AS publishTime, price
FROM t_books t
WHERE t.id = #data.id AND t.book_name = #data.bookName

After compilation the framework produces:

SELECT id, book_name AS bookName, publish_time AS publishTime, price
FROM t_books t
WHERE t.id = '11236562' AND t.book_name = 'JavaScript红皮书'

Example of a $ expression (raw, no quoting):

SELECT id, name, email FROM t_user t
WHERE t.state=$data.state AND t.type IN ($data.types)

Dynamic code blocks allow loops and conditionals inside SQL templates:

<% for (let [name, version] of data.list) { %>
  AND t1.en_name = #name AND t1.version = #version
<% } %>

The article also shows how to compile a template into executable JavaScript:

let template = `
<ul>
<% for(let i=0; i < data.users.length; i++) { %>
  <li><%= data.users[i] %></li>
<% } %>
</ul>`;

Declarative transaction support is illustrated with a decorator:

function Transaction() {
  return (target, propKey, descriptor) => {
    const original = descriptor.value;
    descriptor.value = async function(...args) {
      try {
        await this.ctx.app.mysql.beginTransactionScope(async (conn) => {
          this.ctx.conn = conn;
          await original.apply(this, args);
        }, this.ctx);
      } catch (error) {
        this.ctx.body = { error };
      }
    };
  };
}

Project structure based on the Midway framework is presented, showing directories for controllers, services, mappings, and the Node‑MyBatis core.

To improve developer experience, the authors built a TypeScript generation tool (tts) that creates interface definitions from database tables, enabling IDE features such as auto‑completion, type checking, and advanced utility types (Pick, Partial, etc.).

Finally, the article discusses future work: caching layers (first‑ and second‑level cache), custom SQL methods/tags, VSCode language‑service integration for SQL syntax highlighting, formatting, and real‑time preview of generated SQL.

In summary, the Wukong Activity Platform’s data‑persistence layer combines raw MySQL drivers, optional ORM usage, and a custom Node‑MyBatis framework to retain the expressive power of raw SQL while providing modern developer ergonomics such as TypeScript typing, declarative transactions, and dynamic SQL building.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

TypeScriptBackend DevelopmentNode.jsmysqlMyBatisORMSQL injection
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.