{"id":19146501,"url":"https://github.com/kahsolt/sqlbuilder","last_synced_at":"2025-02-22T19:49:47.787Z","repository":{"id":113306688,"uuid":"115918341","full_name":"Kahsolt/SQLBuilder","owner":"Kahsolt","description":"Hyperlight-weight sqlbuilder generating SQL of DDL(table-related), DML and simple DQL; mainly aimed for SQLite3.","archived":false,"fork":false,"pushed_at":"2020-08-14T03:12:47.000Z","size":155,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-03T16:28:48.164Z","etag":null,"topics":["lightweight","sql","sql-builder","sqlite-database","sqlite3","toy-project"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kahsolt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-01T12:38:38.000Z","updated_at":"2020-08-14T03:12:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"de243909-c91d-4f23-8270-6e26d382e076","html_url":"https://github.com/Kahsolt/SQLBuilder","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kahsolt%2FSQLBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kahsolt%2FSQLBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kahsolt%2FSQLBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kahsolt%2FSQLBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kahsolt","download_url":"https://codeload.github.com/Kahsolt/SQLBuilder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240229935,"owners_count":19768588,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lightweight","sql","sql-builder","sqlite-database","sqlite3","toy-project"],"created_at":"2024-11-09T07:44:22.051Z","updated_at":"2025-02-22T19:49:47.768Z","avatar_url":"https://github.com/Kahsolt.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SQLBuilder\n\n---\n    Hyperlight-weight sqlbuilder generating SQL of DDL(table-related), \n    DML and simple DQL; mainly aimed for SQLite3.\n    \n## General\n    This toy tool is NOT FOR \n      - those expert in writing optimized SQL\n      - who wants to take control in every details\n    just meant FOR\n      - who always forgets SQL syntax at a while\n      - who is just lazy enough (2333)\n  - Syntax Support(only differs in CREATE/TRUNCATE TABLE so far...)\n    - SQLite3\n    - MySQL (experimental)\n  - Examples\n    - Code: tk/kahsolt/sqlbuilder/example/Example.java\n    - Output: run `java -jar sqlbuilder.jar`\n      * 实际生成的sql只有一行，下文为了方便阅读而手工调整了缩进 :) *\n  - IDE Build\n    - Intellij artifact - JAR\n    \n## ChangeLog\n  - v0.3.3\n```java\n// 1.一些细节bugfix\n// 2.增加ALTER TABLE ADD COLUMN\nsqlBuilder.alterTable(\"Player\")\n    .add(\"moe\").type(\"INT\").defaultValue(0).end()   // this one closes add()\n    .add(\"warui\").type(\"FLOAT\").notNull().end()\n    .end(); // this one closes alterTable()\n```\n```sql\nALTER TABLE Player ADD moe INTEGER DEFAULT 0, warui FLOAT NOT NULL;\n```\n\n  - v0.3\n```java\n// 1.增加defaultValues()函数，用于产生一行DEFAULT VALUES\nsqlBuilder.insert(\"Test\").into().defaultValues().end();\n// 2.支持生成含参模板(?)，可用在无参数的values()，单参数的set()，无参数的运算符函数如eq()/gt()/like()/between()等等\nsqlBuilder.insert(\"Unknown\").into(\"leave\", \"me\", \"blank\").values().end();   // 产生的问号个数与into()中列数相同\nsqlBuilder.update(\"People\").set(\"me\").end();\nsqlBuilder.select(\"name\").from(\"User\")\n    .where(\"gender\").eq()\n        .and(\"gender\").between().end();\n// 3.选择常量/变量\nsqlBuilder.select(\"@@IDENTITY\").end();\n// 3.支持REPLACE\nsqlBuilder.replace(\"User\").into(\"id\", \"username\")\n    .values(5, \"hahah\").end();\n// 4.修复外键约束生成的语法错误的BUG，增加支持设置外键删改策略\n```\n```sql\nINSERT INTO Test DEFAULT VALUES;\n\nINSERT INTO Unknown(leave, me, blank) VALUES(?, ?, ?);\nUPDATE People SET me = ?;\nSELECT name FROM User WHERE gender = ? AND gender BETWEEN ? AND ?;\n\nSELECT @@IDENTITY;\n\nREPLACE INTO User(id, username) VALUES(5, 'hahah');\n\nFOREIGN KEY(poster) REFERENCES User(id) ON UPDATE RESTRICT ON DELETE RESTRICT\n```\n\n  - v0.2\n```java\n// 1.去掉强制转子查询的sub()函数（已经可以自动判断）\n// 2.分步建表：理解表的结构\nTable table = sqlBuilder.createTable(\"Test\", true);\nTable.Column column = new Table.Column(\"key\");\ncolumn.unique();\ncolumn.defaultValue(0);\ntable.column(column);\ncolumn = new Table.Column(\"val\");\ncolumn.type(\"FLOAT\");\ncolumn.defaultValue(null);\ntable.column(column);\nsql = table.end();  // 调用end()才能输出结果\n```\n```sql\nCREATE OR REPLACE TABLE Test (\n  key INTEGER UNIQUE DEFAULT 0, \n  val FLOAT NULL\n);\n```\n\n  - v0.1\n    基本功能OK，参考下文初版Quick Start\n\n## Quick Start\n```java\nimport tk.kahsolt.sqlbuilder.*;\nSQLBuilder sqlBuilder = new SQLBuilder();   // 默认语法为SQLITE，可传入Dialect.MYSQL\nString sql = sqlBuilder.xxx().yyy()...zzz();// 可使用的方法参考下文\n                                            // 若调用不当无法产生SQL时会抛出NullPointerException，可酌情处理\nSystem.out.println(sql);\n```\n### Table\n   - CREATE\n```java\nsqlBuilder.createTable(\"Message\")\n    .column(\"id\").autoIncrement().end()             // autoIncrement 默认为 Integer + PK\n    .column(\"poster\").referencesTo(\"User\").end()    // referencesTo 默认指向参考表的字段 id(小写)\n    .column(\"content\").type(100).defaultValue(\"这货啥也没说...\").end()    // type 默认为 VARCHAR，可仅指出长度\n    .column(\"likes\").defaultValue(0).end()          // type 从defaultValue中推测(仅INT/FLOAT/VARCHAR)\n    .column(\"create_time\").initSetCurrent().end()   // type 从initSetCurrent或updateSetCurrent推测为TIMESTAMP\n    .column(\"update_time\").updateSetCurrent().end() // updateSetCurrent 默认隐含了 initSetCurrent\n    .engine(\"MyISAM\").charset(\"utf8mb4\").comment(\"发帖记录表，也没什么卵用\").end();\n```\nSQLite Syntax:\n```sql\nCREATE TABLE IF NOT EXISTS Message (\n  id INTEGER PRIMARY KEY AUTOINCREMENT, \n  poster INTEGER NULL REFERENCES User(id), \n  content VARCHAR(100) DEFAULT '这货啥也没说...', \n  likes INTEGER DEFAULT 0, \n  create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, \n  update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n); \nCREATE TRIGGER update_update_time \n  AFTER UPDATE ON Message \n  FOR EACH ROW \n  WHEN NEW.update_time \u003c= OLD.update_time \nBEGIN \n  UPDATE Message SET update_time = CURRENT_TIMESTAMP WHERE update_time = OLD.update_time; \nEND;\n```\nMySQL Syntax:\n```sql\nCREATE TABLE IF NOT EXISTS Message (\n  id INT PRIMARY KEY AUTO_INCREMENT, \n  poster INT NULL REFERENCES User(id), \n  content VARCHAR(100) DEFAULT '这货啥也没说...', \n  likes INT DEFAULT 0, \n  create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, \n  update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP\n) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='发帖记录表，也没什么卵用';\n```\n\n  - DROP\n```java\nsqlBuilder.dropTable(\"Message\").end();\n```\n```sql\nDROP TABLE IF EXISTS Message;\n```\n\n  - TRUNCATE\n```java\nsqlBuilder.truncateTable(\"User\").end();\n```\nSQLite Syntax:\n```sql\nBEGIN; \n  DELETE FROM User; \n  UPDATE sqlite_sequence SET seq = 0 WHERE name = 'User'; \nCOMMIT; \nVACUUM User;\n```\nMySQL Syntax:\n```sql\nTRUNCATE TABLE User;\n```\n\n### Query\n  - INSERT\n```java\nsqlBuilder.insert(\"Test\").into()     // 无参 into() 不生成插入列名表\n    .values(\"The\", 2, \"parameter\").end();\n```\n```sql\nINSERT INTO Test VALUES('The', 2, 'parameter');\n```\n```java\nsqlBuilder.insert(\"User\").into(\"username\", \"password\", \"time\")\n    .values(\"kahsolt\", 13759, null)           // 单句插入多行\n    .values(\"luper\", 18392, \"Now\").end();\n```\n```sql\nINSERT INTO User(username, password, time)\n  VALUES('kahsolt', 13759, NULL), ('luper', 18392, 'Now');\n```\n\n  - UPDATE\n```java\nsqlBuilder.update(\"User\")\n    .set(\"name\", \"kahsolt\")     // 单句更新多列\n    .set(\"age\", 12).end();\n```\n```sql\nUPDATE User SET name = 'kahsolt', age = 12;\n```\n```java\nsqlBuilder.update(\"User\")\n    .set(\"isAllowed\", false).where(\"age\").lt(18).end(); // 带简单where条件\n```\n```sql\nUPDATE User SET isAllowed = 0 WHERE age \u003c 18;\n```\n\n  - DELETE\n```java\nsqlBuilder.delete(\"User\")\n    .where(\"username\").eq(\"kahsolt\")      // 生成的where句中and和or分条件不带括号，请自行组织顺序 :(\n        .and(\"age\").between(13, 31)\n        .or(\"gender\").like(\"秀吉\").end(); // like(x) 默认产生 LIKE '%x%', 可带参数raw传入原生SQL片段\n```\n```sql\nDELETE FROM User \n  WHERE username = 'kahsolt' \n    AND age BETWEEN 13 AND 31 \n    OR gender like '%秀吉%';\n```\n\n  - SELECT\n```java\nsqlBuilder.select(true, \"name\", \"COUNT(price)\").from(\"`Order`\")\n    .join(\"Author\").on(\"author\")                // join() 默认方向为INNER, on() 默认指向参照表的id字段 =\u003e INNER JOIN Author ON author = Author.id\n    .join(\"Book\", \"OUTER\").on(\"book\", \"title\")  // =\u003e OUTER JOIN Book ON book = Book.title\n    .where(\"year\").between(2016, 2018)\n    .groupBy(\"author\")\n    .having(\"COUNT(title)\").gt(5)\n    .orderBy(\"year\", true)\n    .limit(100).end();\n```\n```sql\nSELECT DISTINCT name, COUNT(price) FROM `Order` \n  INNER JOIN Author ON author = Author.id \n  OUTER JOIN Book ON book = Book.title \n  WHERE year BETWEEN 2016 AND 2018 \n  GROUP BY author \n    HAVING COUNT(title) \u003e 5 \n  ORDER BY year DESC \n  LIMIT 100;\n```\n```java\nsqlBuilder.select(\"name\").from(\"User\")\n    .where(\"age\").gt(\n        mysqlBuilder.select(\"age\").from(\"User\")\n            .where(\"gender\").eq(\"female\").any().end()   // 量词型子查询，可调用any()/some()/all()\n    ).end();\n```\n```sql\nSELECT name FROM User \n  WHERE age \u003e ANY(\n    SELECT age FROM User \n      WHERE gender = 'female'\n  );\n```\n```java\nsqlBuilder.select(\"name\").from(\"User\")\n    .where(\"age\", \"job\").in(                            // 集合型子查询，可调用in()/notin()，可传入多个列名(列构造器)\n        mysqlBuilder.select(\"age\", \"job\").from(\"User\")\n            .where(\"gender\").eq(\"female\").end()\n    ).end();\n```\n```sql\nSELECT name FROM User \n  WHERE (age, job) IN (\n    SELECT age, job FROM User \n      WHERE gender = 'female'\n  );\n```\n\n### Transaction\n```java\nsqlBuilder.begin()\n    .block(mysqlBuilder.insert(\"User\").into(\"username\", \"age\")  // 可以用SQLBuilder嵌套造句\n        .values(\"kahsolt\", 13)\n        .values(\"luper\", 31).end())\n    .block(\"SELECT COUNT(*) FROM User;\")                        // 也可以传手写的SQL\n    .commit();\n```\n```sql\nBEGIN; \n  INSERT INTO User(username, age) \n    VALUES('kahsolt', 13), ('luper', 31); \n  SELECT COUNT(*) FROM User; \nCOMMIT;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkahsolt%2Fsqlbuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkahsolt%2Fsqlbuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkahsolt%2Fsqlbuilder/lists"}