Sqler

一个功能强大且灵活的 Dart SQL 查询构建器,专注于 MySQL 和 SQLite3 支持,采用流畅的接口设计。

Pub Version Dev Donate issues-closed issues-open Contributions

功能特性

  • 流畅接口:使用方法链构建 SQL 查询,提高可读性
  • 类型安全:在编译时安全地构造查询
  • 全面支持:SELECT、INSERT、UPDATE、DELETE 操作
  • 高级子句:WHERE、JOIN、GROUP BY、HAVING、ORDER BY、LIMIT
  • 参数化查询:支持命名参数以防止 SQL 注入
  • 适当转义:自动字段引用和值转义
  • 复杂操作:子查询、CASE 语句、聚合函数
  • MySQL 优化:专门针对 MySQL 语法和特性设计
  • SQLite 优化:专门针对 SQLite 语法和特性设计

安装

将以下内容添加到包的 pubspec.yaml 文件中:

dependencies:
  sqler: 

dart pub add sqler

然后运行:

dart pub get

快速开始

import 'package:sqler/sqler.dart';

void main() {
  // 创建表
  var books = MTable(
    name: 'books',
    fields: [
      MFieldInt(name: 'id', isPrimaryKey: true, isAutoIncrement: true),
      MFieldVarchar(name: 'name', length: 255),
      MFieldVarchar(name: 'author', length: 255),
      MFieldInt(name: 'publication_year'),
      MFieldDate(name: 'published_date'),
      MFieldText(name: 'content'),
    ],
  );

  // 简单的 SELECT 查询
  var query = Sqler()
    .addSelect(QSelect('name'))
    .addSelect(QSelect('published_date'))
    .from(QField('books'))
    .where(WhereOne(QField('publication_year'), QO.EQ, QVar(1980)))
    .orderBy(QOrder('name'))
    .limit(10);

  print(query.toSQL());

  /// 打印 SQLite 格式:
  print(query.toSQL<Sqlite>());
}

SQLite

要以 SQLite 格式生成 SQL 查询,请将 Sqlite 作为类型参数传递给 toSQL 函数:

query.toSQL<Sqlite>()

这确保生成的 SQL 语法与 SQLite 兼容。

核心类

Sqler

主查询构建器类,提供流畅的接口来构造 SQL 查询。

QField

表示数据库字段并进行适当引用:

QField('users.name')     // users.`name`
QField('table_name')     // `table_name`

QVar

表示值并进行适当转义:

QVar('string value')     // 'string value'
QVar(123)               // 123
QVar(true)              // true
QVar(null)              // NULL

QSelect

表示 SELECT 字段,可选择别名:

QSelect('name')                    // `name`
QSelect('users.name', 'user_name') // users.`name` AS `user_name`

使用示例

基本 SELECT 查询

var query = Sqler()
  .addSelect(QSelect('id'))
  .addSelect(QSelect('name'))
  .addSelect(QSelect('email'))
  .from(QField('users'));

print(query.toSQL());
// SELECT `id`, `name`, `email` FROM `users`

带 WHERE 条件的 SELECT

var query = Sqler()
  .addSelect(QSelect('*'))
  .from(QField('users'))
  .where(AndWhere([
    WhereOne(QField('active'), QO.EQ, QVar(true)),
    WhereOne(QField('age'), QO.GT, QVar(18))
  ]));

print(query.toSQL());
// SELECT * FROM `users` WHERE ( ( `active` = true ) ) AND ( ( `age` > 18 ) )

带 JOIN 的 SELECT

var query = Sqler()
  .addSelect(QSelect('users.name'))
  .addSelect(QSelect('profiles.bio'))
  .from(QField('users'))
  .join(LeftJoin('profiles', On([
    Condition(QField('users.id'), QO.EQ, QField('profiles.user_id'))
  ])))
  .where(WhereOne(QField('users.active'), QO.EQ, QVar(true)));

print(query.toSQL());
// SELECT `users`.`name`, `profiles`.`bio` FROM `users` 
// LEFT JOIN `profiles` ON ( ( `users`.`id` = `profiles`.`user_id` ) ) 
// WHERE ( `users`.`active` = true )

INSERT 操作

// 单记录插入
var query = Sqler()
  .insert(QField('users'), [
    {
      'name': QVar('John Doe'),
      'email': QVar('[email protected]'),
      'active': QVar(true),
      'age': QVar(30)
    }
  ]);

print(query.toSQL());
// INSERT INTO `users` (`name`, `email`, `active`, `age`) 
// VALUES ('John Doe', '[email protected]', true, 30)
// 多记录插入
var query = Sqler()
  .insert(QField('users'), [
    {
      'name': QVar('John Doe'),
      'email': QVar('[email protected]')
    },
    {
      'name': QVar('Jane Smith'),
      'email': QVar('[email protected]')
    }
  ]);

print(query.toSQL());
// INSERT INTO `users` (`name`, `email`) 
// VALUES ('John Doe', '[email protected]'), ('Jane Smith', '[email protected]')

UPDATE 操作

var query = Sqler()
  .update(QField('users'), {
    'name': QVar('Updated Name'),
    'email': QVar('[email protected]')
  })
  .where(WhereOne(QField('id'), QO.EQ, QVar(1)));

print(query.toSQL());
// UPDATE `users` SET `name` = 'Updated Name', `email` = '[email protected]' 
// WHERE ( `id` = 1 )

DELETE 操作

var query = Sqler()
  .delete()
  .from(QField('users'))
  .where(WhereOne(QField('active'), QO.EQ, QVar(false)));

print(query.toSQL());
// DELETE FROM `users` WHERE ( `active` = false )

带 GROUP BY 和 HAVING 的复杂查询

var query = Sqler()
  .addSelect(QSelect('department'))
  .addSelect(QSelectFunc('COUNT', [QField('id')], 'employee_count'))
  .from(QField('employees'))
  .where(WhereOne(QField('active'), QO.EQ, QVar(true)))
  .groupBy(QField('department'))
  .having(HavingOne(QSelectFunc('COUNT', [QField('id')]), QO.GT, QVar(5)))
  .orderBy(QOrder('employee_count', OrderDirection.DESC));

print(query.toSQL());
// SELECT `department`, COUNT(`id`) AS `employee_count` FROM `employees` 
// WHERE ( `active` = true ) GROUP BY `department` 
// HAVING ( COUNT(`id`) > 5 ) ORDER BY `employee_count` DESC

参数化查询

var query = Sqler()
  .addSelect(QSelect('*'))
  .from(QField('users'))
  .where(WhereOne(QField('name'), QO.EQ, QParam('user_name')))
  .param('user_name', QVar('John Doe'));

print(query.toSQL());
// SELECT * FROM `users` WHERE ( `name` = :user_name )

var params = query.getParams();
// {'user_name': QVar('John Doe')}

操作符

QO 类提供各种比较操作符:

  • QO.EQ - 等于 (=)
  • QO.NE - 不等于 (!=)
  • QO.GT - 大于 (>)
  • QO.GTE - 大于或等于 (>=)
  • QO.LT - 小于 (<)
  • QO.LTE - 小于或等于 (<=)
  • QO.LIKE - LIKE 模式匹配
  • QO.NOT_LIKE - NOT LIKE 模式匹配
  • QO.IN - IN 列表
  • QO.NOT_IN - NOT IN 列表
  • QO.IS_NULL - IS NULL
  • QO.IS_NOT_NULL - IS NOT NULL

WHERE 条件

基本条件

WhereOne(QField('status'), QO.EQ, QVar('active'))

组合条件

AndWhere([
  WhereOne(QField('active'), QO.EQ, QVar(true)),
  WhereOne(QField('age'), QO.GTE, QVar(18))
])

OrWhere([
  WhereOne(QField('role'), QO.EQ, QVar('admin')),
  WhereOne(QField('role'), QO.EQ, QVar('moderator'))
])

JOIN 类型

  • InnerJoin - INNER JOIN
  • LeftJoin - LEFT JOIN
  • RightJoin - RIGHT JOIN
.join(InnerJoin('table2', On([
  Condition(QField('table1.id'), QO.EQ, QField('table2.table1_id'))
])))

🚀 Beta 版本 - 您的贡献很重要!

Sqler 目前处于 beta 版本! 我们很高兴与 Dart 社区分享这个强大的 SQL 查询构建器,我们希望得到您的帮助使其变得更好。

您可以如何帮助

这个 beta 版本意味着我们正在积极寻求像您这样的开发者的反馈和贡献!以下是一些参与方式:

  • 🐛 错误报告:发现了不符合预期的问题?请提交 issue!
  • 📝 文档:帮助我们改进文档、示例和指南
  • 💡 功能请求:有新功能的想法?我们很乐意听取!
  • 🔧 代码贡献:提交 Pull Request 帮助改进代码库
  • 🧪 测试:在您的项目中使用 Sqler 并分享您的体验

表达您的支持

由于我们使用 星标和评分作为主要指标 来衡量社区兴趣并指导我们的开发优先级,如果您能:

  • 在 GitHub 上给我们加星:帮助其他人发现 Sqler!
  • 👍 喜欢这个包:您的支持激励我们不断改进
  • 📢 与他人分享:告诉其他开发者关于 Sqler

您的反馈和贡献对于帮助我们构建最好的 Dart SQL 查询构建器非常宝贵。感谢您成为我们旅程的一部分!🙏

贡献

欢迎贡献!请随时提交 Pull Request。对于重大更改,请先开启一个 issue 讨论您想要更改的内容。

许可证

本项目采用 MIT 许可证 - 详见 LICENSE 文件。

代码仓库

https://github.com/uproid/sqler