npm package: @mznjs/node-mysql
Description: 快速操作mysql的TypeScript Nodejs库
Author: supbose
Latest version: 1.1.0

# @mznjs/node-mysql 使用示例

本文档提供了 `@mznjs/node-mysql` 库的详细使用示例，包括数据库连接、查询、插入、更新、删除等操作。

## 基本用法

### 1. 引入库和创建连接

```javascript
// 引入库
import { Database } from '@mznjs/node-mysql';

// 创建数据库连接配置
const dbConfig = {
  host: 'localhost',
  user: 'root',
  password: 'your_password',
  database: 'test_db'
};

// 创建数据库实例
const db = new Database(dbConfig);
```

### 2. 查询数据

#### 查询所有记录

```javascript
// 查询 users 表的所有记录
async function getAllUsers() {
  try {
    const result = await db.table('users').get();
    console.log('查询结果:', result);
    // 结果格式: { code: 0, msg: 'SUCCESS', data: [...] }
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

#### 带条件查询

```javascript
// 查询特定条件的记录
async function getUsersByCondition() {
  try {
    // WHERE 条件查询
    const result = await db
      .table('users')
      .where({ status: 1, age: 25 })
      .get();
    console.log('条件查询结果:', result);
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

#### 排序和限制字段

```javascript
// 排序和限制查询字段
async function getSortedUsers() {
  try {
    const result = await db
      .table('users')
      .field(['id', 'name', 'age'])
      .where({ status: 1 })
      .sort({ create_time: 'DESC' })
      .get();
    console.log('排序查询结果:', result);
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

#### 模糊查询

```javascript
// 模糊查询
async function searchUsers() {
  try {
    // 模糊查询数组格式: [字段名, 搜索值, 匹配模式]
    // 匹配模式可选值: 'top' (开头匹配), 'end' (结尾匹配), 'both' (两端匹配，默认)
    const result = await db
      .table('users')
      .like([
        ['name', '张', 'top'],  // 名字以'张'开头
        ['address', '北京', 'both']  // 地址包含'北京'
      ])
      .get();
    console.log('模糊查询结果:', result);
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

### 3. 插入数据

#### 插入单条数据

```javascript
// 插入单条数据
async function addUser() {
  try {
    const result = await db
      .table('users')
      .add({
        name: '张三',
        age: 28,
        email: 'zhangsan@example.com',
        status: 1,
        create_time: new Date()
      })
      .get();
    console.log('插入结果:', result);
    // 结果格式: { code: 0, msg: 'SUCCESS', data: { add: 1, insertId: 123 } }
  } catch (error) {
    console.error('插入失败:', error);
  }
}
```

#### 插入数据（忽略重复项）

```javascript
// 插入数据并忽略重复项
async function addUserWithIgnore() {
  try {
    const result = await db
      .table('users')
      .add(
        {
          id: 1,
          name: '张三',
          age: 28
        },
        true  // 忽略重复项
      )
      .get();
    console.log('插入结果:', result);
  } catch (error) {
    console.error('插入失败:', error);
  }
}
```

#### 批量插入数据

```javascript
// 批量插入数据
async function batchAddUsers() {
  try {
    const users = [
      { name: '李四', age: 25, status: 1 },
      { name: '王五', age: 30, status: 1 },
      { name: '赵六', age: 35, status: 0 }
    ];
    
    const result = await db
      .table('users')
      .addAll(users)
      .get();
    console.log('批量插入结果:', result);
  } catch (error) {
    console.error('批量插入失败:', error);
  }
}
```

### 4. 更新数据

```javascript
// 更新数据
async function updateUser() {
  try {
    const result = await db
      .table('users')
      .where({ id: 1 })
      .update({
        age: 29,
        update_time: new Date()
      })
      .get();
    console.log('更新结果:', result);
    // 结果格式: { code: 0, msg: 'SUCCESS', data: { affectedRows: 1 }, update: '更新了1个数据' }
  } catch (error) {
    console.error('更新失败:', error);
  }
}
```

### 5. 删除数据

```javascript
// 删除数据
async function deleteUser() {
  try {
    const result = await db
      .table('users')
      .where({ id: 1 })
      .del()
      .get();
    console.log('删除结果:', result);
    // 结果格式: { code: 0, msg: 'SUCCESS', data: { del: 1 }, del: '删除1个数据' }
  } catch (error) {
    console.error('删除失败:', error);
  }
}
```

> **注意**：执行没有 WHERE 条件的 DELETE 语句会删除表中所有数据，系统会输出警告信息。

### 6. 计数查询

```javascript
// 计数查询
async function countUsers() {
  try {
    const result = await db
      .table('users')
      .where({ status: 1 })
      .count()
      .get();
    console.log('计数结果:', result);
    // 结果格式: { code: 0, msg: 'SUCCESS', data: { count: 10 }, count: '查询到10个数据' }
  } catch (error) {
    console.error('计数失败:', error);
  }
}
```

### 7. 表连接查询

```javascript
// 表连接查询
async function joinTables() {
  try {
    const result = await db
      .table('users')
      .leftJoin('orders', 'users.id = orders.user_id')
      .where({ 'users.status': 1 })
      .field(['users.id', 'users.name', 'orders.order_no', 'orders.amount'])
      .get();
    console.log('连接查询结果:', result);
  } catch (error) {
    console.error('连接查询失败:', error);
  }
}
```

支持的连接类型：
- `join(type, table, condition)` - 通用连接方法
- `leftJoin(table, condition)` - LEFT JOIN
- `rightJoin(table, condition)` - RIGHT JOIN
- `innerJoin(table, condition)` - INNER JOIN

```typescript
// 使用便捷方法进行连接
const result1 = await db
  .table('users')
  .leftJoin('orders', 'users.id = orders.user_id')
  .get()

const result2 = await db
  .table('users')
  .innerJoin('user_roles', 'users.id = user_roles.user_id')
  .get()

const result3 = await db
  .table('products')
  .rightJoin('categories', 'products.category_id = categories.id')
  .get()
```

### 8. 执行自定义 SQL

```javascript
// 执行自定义 SQL 语句
async function executeCustomSql() {
  try {
    const sql = 'SELECT u.id, u.name, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id HAVING order_count > ?';
    const result = await db.sqlQuery(sql, ['COUNT']);
    console.log('自定义 SQL 结果:', result);
  } catch (error) {
    console.error('执行失败:', error);
  }
}
```

### 9. 查询所有记录（直接执行 SQL）

```javascript
// 直接执行 SQL 查询所有记录
async function queryAllData() {
  try {
    const sql = 'SELECT * FROM users WHERE age > ? AND status = ?';
    const params = [25, 1];
    const result = await db.queryAll(sql, params);
    console.log('查询结果:', result);
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

### 10. 自动关闭连接

```javascript
// 查询后自动关闭连接
async function queryAndClose() {
  try {
    const result = await db
      .table('users')
      .where({ status: 1 })
      .get(true);  // 传入 true 表示查询后自动关闭连接
    console.log('查询结果:', result);
  } catch (error) {
    console.error('查询失败:', error);
  }
}
```

或者手动关闭连接：

```javascript
// 手动关闭连接
async function closeConnection() {
  try {
    await db.close();
    console.log('数据库连接已关闭');
  } catch (error) {
    console.error('关闭连接失败:', error);
  }
}
```

## 高级用法

### 事务处理

> 注意：当前版本的库暂未提供显式的事务API，但可以通过 `sqlQuery` 方法手动实现事务处理。

```javascript
// 手动实现事务处理
async function executeTransaction() {
  try {
    // 开始事务
    await db.sqlQuery('START TRANSACTION');
    
    // 执行操作
    await db.table('users').where({ id: 1 }).update({ balance: 900 });
    await db.table('orders').add({ user_id: 1, amount: 100, status: 1 });
    
    // 提交事务
    await db.sqlQuery('COMMIT');
    console.log('事务执行成功');
  } catch (error) {
    // 回滚事务
    await db.sqlQuery('ROLLBACK');
    console.error('事务执行失败，已回滚:', error);
  }
}
```

### 完整的错误处理

```javascript
// 完整的错误处理示例
async function robustDatabaseOperation() {
  try {
    const result = await db
      .table('non_existent_table')  // 故意使用不存在的表名
      .get();
      
    if (result.code === 0) {
      console.log('操作成功:', result.data);
    } else {
      console.warn('操作返回非成功状态:', result.code, result.msg);
    }
  } catch (error) {
    console.error('发生异常:', error.message);
    // 可以根据错误类型进行不同的处理
    if (error.code === 'ER_NO_SUCH_TABLE') {
      console.error('表不存在，请检查表名是否正确');
    } else if (error.code === 'ER_ACCESS_DENIED_ERROR') {
      console.error('数据库访问被拒绝，请检查用户名和密码');
    } else {
      console.error('未知错误:', error);
    }
  } finally {
    // 无论成功失败，确保连接被关闭
    try {
      await db.close();
    } catch (closeError) {
      console.error('关闭连接时发生错误:', closeError);
    }
  }
}
```

### 多表插入
```javascript
// 创建数据库连接实例
const db = new Database({
  host: 'localhost',
  user: 'your_username',
  password: 'your_password',
  database: 'your_database'
});

// 示例1: 向多张表插入单条数据
async function insertSingleData() {
  try {
    const result = await db.adds({
      'users': {
        name: 'John Doe',
        email: 'john@example.com',
        created_at: new Date()
      },
      'user_profiles': {
        user_id: 1, // 假设用户ID为1
        avatar: 'avatar.jpg',
        bio: 'Hello World'
      },
      'user_settings': {
        user_id: 1,
        theme: 'dark',
        notifications: true
      }
    });
    
    console.log('插入结果:', result);
    // 输出: { code: 0, msg: '多表插入成功', data: [...] }
    
  } catch (error) {
    console.error('插入失败:', error);
  } finally {
    await db.close();
  }
}

// 示例2: 向多张表批量插入数据
async function insertBatchData() {
  try {
    const result = await db.adds({
      'categories': [
        { name: '电子产品', description: '各类电子产品' },
        { name: '服装', description: '男女服装' },
        { name: '图书', description: '各类图书' }
      ],
      'tags': [
        { name: '热门' },
        { name: '新品' },
        { name: '推荐' }
      ]
    });
    
    console.log('批量插入结果:', result);
    
  } catch (error) {
    console.error('批量插入失败:', error);
  } finally {
    await db.close();
  }
}
```
## 新增功能说明
1. **AddsConfig 接口：**
   - 定义了多表插入的配置结构
   - 键为表名，值为要插入的数据（支持单条或批量）
2. **TransactionResult 接口：**
   - 定义了事务执行结果的结构
   - 包含影响行数、插入ID和表名
3. **adds 方法：**
   - 支持向多个表同时插入数据
   - 使用事务确保数据一致性
   - 如果任何一个插入操作失败，会自动回滚所有操作
   - 返回详细的执行结果
4. **事务相关方法：**
   - `beginTransaction()` - 开启事务
   - `commitTransaction()` - 提交事务
   - `rollbackTransaction()` - 回滚事务
   - `executeInTransaction()` - 在事务中执行查询


## 使用建议

1. **连接管理**
   - 对于长时间运行的应用，建议保持连接并在适当的时候关闭
   - 对于短期任务，可以使用 `get(true)` 自动关闭连接
   - 避免频繁创建和关闭连接，这会影响性能

2. **安全性**
   - 始终使用参数化查询（通过 `where`、`like` 等方法），避免 SQL 注入
   - 谨慎使用没有 WHERE 条件的 UPDATE 和 DELETE 操作
   - 不要在客户端代码中暴露数据库凭证

3. **性能优化**
   - 只查询需要的字段，使用 `field` 方法限制返回字段
   - 使用索引字段进行查询和排序
   - 对于大量数据操作，考虑使用批量操作（如 `addAll`）

4. **错误处理**
   - 始终使用 try-catch 包装数据库操作
   - 注意处理连接失败、断开重连等异常情况
   - 根据返回的错误代码进行相应的业务逻辑处理

通过上述示例，您应该能够全面了解如何使用 `@mznjs/node-mysql` 库进行各种数据库操作。如有任何问题或需要进一步的帮助，请参考源代码或提交 issue。