拓展阅读

linq

querydsl

ORM-01-Hibernate、MyBatis、EclipseLink、Spring Data JPA、TopLink、ActiveJDBC、Querydsl 和 JOOQ 对比

ORM-02-Hibernate 对象关系映射(ORM)框架

ORM-02-JPA Java Persistence API 入门介绍

orm-04-Spring Data JPA 入门介绍

ORM-05-javalite activejdbc

ORM-06-jooq 入门介绍

ORM-07-querydsl 入门介绍

ORM-08-EclipseLink 入门介绍

ORM-09-TopLink

前言

自己通过 jdbc 实现了一个 数据库查询工具,不过后来想拓展查询功能时,总觉得不够尽兴。

所以在想能不能把 SQL 的构建单独抽离出来。

java-sql-query-builder

Java SQL查询构建器

该项目是用于Java的SQL查询构建器。目前仅支持MySql。

然而,它根据接口编程,因此应该很容易添加其他SQL方言。

该项目在宽松的BSD许可证下获得许可。

例子

以下是使用该项目生成查询的示例:

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/** * 使用 java-sql-query-builder 进行各种查询的示例。 * 重要提示: * 为了清晰起见,省略了异常处理和清理操作。 */ static void 示例() throws SQLException, ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/YourDatabase", "root", "your_password"); PreparedStatement stmt; QbFactory f = new QbFactoryImp(); // 更新给定 id 的 first_name、last_name 和 age... QbUpdate up = f.newUpdateQuery(); up.set(f.newStdField("first_name"), ":first_name") .set(f.newStdField("last_name"), ":last_name") .set(f.newStdField("age"), ":age") .inTable("myTable") .where() .where(f.newStdField("id"), ":id"); stmt = conn.prepareStatement(up.getQueryString()); stmt.setString(up.getPlaceholderIndex(":first_name"), "John"); stmt.setString(up.getPlaceholderIndex(":last_name"), "Citizen"); stmt.setInt(up.getPlaceholderIndex(":age"), 32); stmt.setInt(up.getPlaceholderIndex(":id"), 1024); stmt.executeUpdate(); // 删除所有具有给定年龄值的记录... QbDelete del = f.newDeleteQuery(); del.from("myTable") .where() .where(f.newStdField("age"), ":age"); stmt = conn.prepareStatement(del.getQueryString()); stmt.setInt(del.getPlaceholderIndex(":age"), 32); stmt.executeUpdate(); // 插入一个将 egg_hatched 字段设置为 true 的记录... QbInsert in = f.newInsertQuery(); in.set(f.newStdField("egg_hatched"), ":egg_hatched") .inTable("myTable"); stmt = conn.prepareStatement(in.getQueryString()); stmt.setBoolean(in.getPlaceholderIndex(":egg_hatched"), true); stmt.executeUpdate(); // 简单的选择查询,检索不具有给定 id 的记录的 id、age 和 last_name... QbSelect sel = f.newSelectQuery(); sel.select(f.newStdField("id"), f.newStdField("age"), f.newStdField("last_name")) .from("myTable") .where() .where(f.newStdField("id"), QbWhereOperator.NOT_EQUALS, ":id"); stmt = conn.prepareStatement(sel.getQueryString()); stmt.setInt(sel.getPlaceholderIndex(":id"), 1024); ResultSet rs = stmt.executeQuery(); while (rs.next()) { System.out.println(rs.getInt("id") + ":" + rs.getInt("age") + ":" + rs.getString("last_name")); } // 带有连接的复杂选择查询... sel = f.newSelectQuery(); sel.select(f.newQualifiedField("t1", "id"), f.newQualifiedField("t2", "id")) .from("t1") .join("t2", f.newQualifiedField("t2", "id"), f.newQualifiedField("t1", "t1_id"), QbJoinType.LEFT) .where() .where(f.newStdField("age"), ":age"); stmt = conn.prepareStatement(sel.getQueryString()); stmt.setInt(sel.getPlaceholderIndex(":age"), 45); rs = stmt.executeQuery(); // 记录枚举被省略... // 带有分组的选择查询... sel = f.newSelectQuery(); sel.select(f.newAvg(f.newStdField("age"), "avg_age")) .from("myTable") .groupBy(f.newStdField("first_name")) .having() .where(f.newStdField("avg_age"), QbWhereOperator.GREATER_THAN, ":avg_age"); stmt = conn.prepareStatement(sel.getQueryString()); stmt.setInt(sel.getPlaceholderIndex(":avg_age"), 50); rs = stmt.executeQuery(); // 记录枚举被省略... }

参考资料

https://github.com/danfickle/java-sql-query-builder