项目作者: coajs

项目描述 :
☘️ MySQL database components for coajs, including basic data models, cache data models, distributed ID, etc.
高级语言: TypeScript
项目地址: git://github.com/coajs/coa-mysql.git
创建时间: 2020-05-22T08:21:01Z
项目社区:https://github.com/coajs/coa-mysql

开源协议:MIT License

下载


coa-mysql

GitHub license
npm version
npm downloads
PRs Welcome

English | 简体中文

MySQL database components for coajs, including basic data models, cache data models, distributed ID, etc.

Feature

  • Functional: Basic data connection based on mysql,SQL query based on knex. Pay attention to performance, full-featured, including original library all use methods
  • Lightweight: No more than 1,000 lines of code, do not rely on other third-party libraries
  • Fast and Convenient: Basic data model comes with CRUD operation, no extra code
  • Automatic Cache: Cache data model automatically performs data cache management (cache generation, cache elimination, etc.), cache is based oncoa-redis
  • TypeScript: All written in TypeScript, type constraint, IDE friendship

Component

  • Basic data model MysqlNative: Automatically implement basic CRUD
  • Cache data model MysqlCache: Take over data cache logic on the basic data model
  • Distributed ID MysqlUuid: Lightweight distributed UUID

Quick Start

Install

  1. yarn add coa-mysql

Instance configuration

  1. import { MysqlBin } from 'coa-mysql'
  2. // MySQL configuration
  3. const mysqlConfig = {
  4. host: '127.0.0.1',
  5. port: 3306,
  6. user: 'root',
  7. password: 'root',
  8. charset: 'utf8mb4',
  9. trace: true,
  10. debug: false,
  11. databases: {
  12. main: { database: 'test', ms: 7 * 24 * 3600 * 1000 },
  13. other: { database: 'other', ms: 7 * 24 * 3600 * 1000 },
  14. },
  15. }
  16. // Initialize MySQL basic connection,
  17. // follow-up all models depend on this example
  18. const mysqlBin = new MysqlBin(mysqlConfig)

Basic SQL query

New user table user, the table structure is as follows

  1. CREATE TABLE `user` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Self-increased primary key',
  3. `userId` varchar(32) NOT NULL DEFAULT '' COMMENT 'user ID',
  4. `name` varchar(64) NOT NULL DEFAULT '' COMMENT 'name',
  5. `mobile` varchar(16) NOT NULL DEFAULT '' COMMENT 'mobile',
  6. `avatar` varchar(256) NOT NULL DEFAULT '' COMMENT 'avatar',
  7. `gender` int(11) NOT NULL DEFAULT '0' COMMENT 'gender, 1 male, 2 female',
  8. `language` varchar(16) NOT NULL DEFAULT '' COMMENT 'language',
  9. `status` int(1) NOT NULL DEFAULT '1' COMMENT 'status, 1 normal 2 hidden',
  10. `created` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Create time',
  11. `updated` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Update time',
  12. PRIMARY KEY (`id`) USING BTREE,
  13. UNIQUE KEY `user_userid_unique` (`userId`) USING BTREE
  14. ) COMMENT='User Table';

SQL operations on the user table

  1. // Insert data, see https://knexjs.org/#Builder-insert
  2. mysqlBin.io.table('user').insert({ userId: 'user-a', name: 'A', mobile: '15010001001', gender: 1, language: 'zh-CN', status: 1 })
  3. // Query all data, see https://knexjs.org/#Builder-select
  4. mysqlBin.io.table('user').select()
  5. mysqlBin.io.select('*').from('user')
  6. // Conditional queries, see https://knexjs.org/#Builder-where
  7. mysqlBin.io.table('user').where('status', '=', 1)
  8. // Update data, see http://knexjs.org/#Builder-update
  9. mysqlBin.io.table('user').update({ name: 'AA', gender: 2 }).where({ userId: 'user-a' })
  10. // Delete data, see http://knexjs.org/#Builder-del%20/%20delete
  11. mysqlBin.io.table('user').delete().where({ userId: 'user-a' })

The io in this is a Knex object, can support all the usage of Knex.js

Basic data model

In project engineering, in order to ensure the efficiency and rigor of the query, we will not directly operate the SQL statement. Basic data modules can help us implement CURD operations. Define a basic data model User by as follows

  1. import { MysqlBin, MysqlNative } from 'coa-mysql'
  2. // Define the default structure of User
  3. const userScheme = {
  4. userId: '' as string,
  5. name: '' as string,
  6. mobile: '' as string,
  7. avatar: '' as string,
  8. gender: 1 as number,
  9. language: '' as string,
  10. status: 1 as number,
  11. created: 0 as number,
  12. updated: 0 as number,
  13. }
  14. // Define the User type (automatically generated by the default structure)
  15. type UserScheme = typeof userScheme
  16. // Initialization by base class
  17. const User = new (class extends MysqlNative<UserScheme> {
  18. constructor() {
  19. super(
  20. {
  21. name: 'User', // Table name, default transformation into a `snackcase` format, such as User->user UserPhoto->user_photo
  22. title: 'User Table', // Table note name
  23. scheme: userScheme, // Default structure of the table
  24. pick: ['userId', 'name'], // Field information displayed when querying the list
  25. },
  26. // Binding configuration instance bin
  27. mysqlBin
  28. )
  29. }
  30. // Custom method
  31. async customMethod() {
  32. // Do something
  33. }
  34. })()

Generally, a data sheet corresponds to a model, and after the model is defined, we can operate the model directly to operate the table

  1. // Insert
  2. await User.insert({ name: 'Tom', gender: 1 }) // return 'id001', userId = 'id001' of this data
  3. // Batch insert
  4. await User.mInsert([
  5. { name: 'Tom', gender: 1 },
  6. { name: 'Jerry', gender: 1 },
  7. ]) // return ['id002','id003']
  8. // Update by ID
  9. await User.updateById('id002', { name: 'Lily' }) // return 1
  10. // Batch update by ID array
  11. await User.updateByIds(['id002', 'id003'], { status: 2 }) // return 2
  12. // Update or insert the ID (id exists if updated, if there is no insert)
  13. await User.upsertById('id002', { name: 'Tom', gender: 1 }) // return 1, update one data of userId = 'id02'
  14. await User.upsertById('id004', { name: 'Lily', gender: 1 }) // return 0, insert a new data of userId = 'id04'
  15. // Delete by ID array
  16. await User.deleteByIds(['id003', 'id004']) // return 2
  17. // Query one by ID, the second parameter settings return the data contained in the result
  18. await User.getById('id001', ['name']) // data is {userId:'id001',name:'Tom',gender:1,status:1,...} return {userId:'id001',name:'Tom'}
  19. // Get multiple data by ID array
  20. await User.mGetByIds(['id001', 'id002'], ['name']) // return {id001:{userId:'id001',name:'Tom'},id002:{userId:'id002',name:'Lily'}}
  21. // Truncate table
  22. await User.truncate() // void, do not report an error is to operate successfully
  23. // Custom method
  24. await User.customMethod() // call a custom method

In the actual project, we may need to define multiple models, and there are some public methods on each model. At this time, we can abstract a base class model, other models inherit this base class model

  1. import { CoaMysql } from 'coa-mysql'
  2. // Define the base class of a model by mysqlBin, each model can use this base class
  3. export class MysqlNativeModel<T> extends MysqlNative<T> {
  4. constructor(option: CoaMysql.ModelOption<T>) {
  5. // Configure the instance bin binding
  6. super(option, mysqlBin)
  7. }
  8. // You can also define some general methods
  9. commonMethod() {
  10. // do something
  11. }
  12. }
  13. // Define user model by base model
  14. const User = new (class extends MysqlNativeModel<UserScheme> {
  15. constructor() {
  16. super({ name: 'User', title: 'User Table', scheme: userScheme, pick: ['userId', 'name'] })
  17. }
  18. // Custom method
  19. async customMethodForUser() {
  20. // Do something
  21. }
  22. })()
  23. // Define Manager model by base model
  24. const Manager = new (class extends MysqlNativeModel<ManagerScheme> {
  25. constructor() {
  26. super({ name: 'Manager', title: 'Manager Table', scheme: managerScheme, pick: ['managerId', 'name'] })
  27. }
  28. })()
  29. // Both user model and manager model can call common method
  30. await User.commonMethod()
  31. await Manager.commonMethod()
  32. // Only user models can call custom method
  33. await User.customMethodForUser()

Cache data model

Based on coa-redis to achieve fast and efficient data cache logic, and unify the cache, maintain the life cycle of the cache, to ensure the consistency of cache and mysql data

Need to install coa-redis before use, instructions for use to view here

The method of use of cache data model is exactly the same as the basic data model. Only need to replace the MysqlNative to be MysqlCache

  1. import { CoaMysql, MysqlCache } from 'coa-mysql'
  2. import { RedisBin, RedisCache } from 'coa-redis'
  3. // Define a Redis instance, detail usage see https://github.com/coajs/coa-redis
  4. const redisCache = new RedisCache(new RedisBin({ host: '127.0.0.1' }))
  5. // Define the base class for a cache data model
  6. export class MysqlCacheModel<T> extends MysqlCache<T> {
  7. constructor(option: CoaMysql.ModelOption<T>) {
  8. // Bind the configuration instance and the redisCache instance on this base class
  9. super(option, mysqlBin, redisCache)
  10. }
  11. }
  12. // Define cache user model by cache base class
  13. const UserCached = new (class extends MysqlCacheModel<UserScheme> {
  14. constructor() {
  15. super({ name: 'User', title: 'User Table', scheme: userScheme, pick: ['userId', 'name'] })
  16. }
  17. })()
  18. // Query data
  19. await User.getById('id001') // First query will read the database
  20. await User.getById('id001') // The second call will read data directly from the cache
  21. // Insert, delete, update, just like the basic data model
  22. await User.insert({ name: 'Tom', gender: 1 }) // return 'id001'
  23. await User.updateById('id001', { name: 'Lily' }) // return 1

The cache model automatically maintains and manages caches. If the cache already exists, then call updated updated the data, and automatically remove the latest data from the database when querying the data again. Realization Principle Click here (todo) Learn more