# fastquery
**Repository Path**: fastquery2016/fastquery
## Basic Information
- **Project Name**: fastquery
- **Description**: FastQuery 基于Java语言. 简化Java操作数据层.做为一个开发者,仅仅只需要设计编写DAO接口. 因此,开发代码不得不简洁而优雅.从而,大幅度提升开发效率.
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: http://fastquery.org
- **GVP Project**: No
## Statistics
- **Stars**: 239
- **Forks**: 68
- **Created**: 2016-05-09
- **Last Updated**: 2026-04-21
## Categories & Tags
**Categories**: database-dev
**Tags**: Java持久层框架, orm-framework, Java, java-util, MySQL
## README
## 1. FastQuery 是什么
FastQuery 是一个基于 Java 的数据持久层框架。它的目标不是把数据库访问“包装得更复杂”,而是让开发者以尽可能简单、清晰、稳定的方式操作数据层。框架强调几个核心方向:少量注解、接口式编程、初始化阶段完成大量校验、运行期尽量轻量,以及通过 `@Query`、`@Condition`、`@Set`、`@QueryByNamed` 等机制来表达查询与动态 SQL。
FastQuery 不是传统意义上那种依赖大量 XML、约定隐蔽、运行期才暴露错误的框架。它更希望把许多原本会在运行期才发生的问题,尽量提前到项目初始化阶段发现并阻断。这样做的结果是:开发阶段暴露问题更早,运行阶段的执行路径更直接,代码维护成本也更低。
## 2. FastQuery 的设计目标
如果只用一句话概括 FastQuery,可以这样说:
> **让开发者只面对接口、注解与 SQL,本身不再承担实现类、样板代码和大量重复判断的负担。**
- DAO 只需要定义接口,不需要编写实现类;
- 框架会在初始化阶段为接口生成实现;
- SQL 绑定、方法返回值、分页参数、模板调用等都会在初始化阶段进行检查;
- 如果存在明显问题,项目应当直接无法启动,从而把错误尽可能留在开发阶段解决。
这意味着 FastQuery 的价值,不只是“省代码”,更在于:
- 降低出错面;
- 强迫接口设计更清晰;
- 把动态能力建立在受控规则之上,而不是随意拼接字符串;
- 让查询、分页、事务、多数据源等能力都保持统一风格。
## 3. 适用场景
FastQuery 适合以下类型的项目:
- 以 SQL 为核心表达方式的业务系统;
- 希望接口层清晰、实现层自动生成的数据访问场景;
- 既需要静态 SQL,又需要一定动态 SQL 能力的项目;
- 希望通过注解风格完成绝大部分数据访问定义的项目;
- 对分页、事务、批量更新、多数据源、命名式查询有明确需求的项目。
如果你的项目更希望把 SQL 完整掌握在开发者手里,而不是把查询逻辑大量隐藏在方法名解析或复杂的 Criteria API 中,那么 FastQuery 会更直接。
## 4. 运行环境与依赖
FastQuery 的运行环境要求是 **Java 8+**。
### Maven
```xml
org.fastquery
fastquery
1.0.149
```
### Gradle
```groovy
compile 'org.fastquery:fastquery:1.0.149'
```
## 5. 第一个 FastQuery 程序
第一次使用 FastQuery,需要理解 5 个角色:
- 配置数据源 DataSource
- 配置`fastquery.json`
- 实体类
- DAO 接口
- 通过 `FQuery.getRepository(...)` 获取接口实现并调用
### 5.1 配置数据库数据源
几乎支持所有的主流连接池,这里用 `HikariCP` 做示例:
druid.xml
```xml
```
详细配置选项请参照 https://github.com/brettwooldridge/HikariCP
### 5.2 配置`fastquery.json`
```json
// 配置必须遵循标准的 json 语法.
{
"scope":[
{
"config": "hikari", // 连接池厂商,如,"hikari","druid","c3p0" 等等
"dataSourceName": "xkdb", // 这里指定由上个步骤配置的数据源名称
"basePackages": [ // 该数据源的作用范围
"org.fastquery.example", // 包地址
"org.fastquery.dao.UserInfoDBService" // 完整类名称
]
}
]
}
```
### 5.3 定义实体
```java
public class Student
{
private String no;
private String name;
private String sex;
private Integer age;
private String dept;
// getter / setter 省略...
}
```
这里有一个非常关键的约定:**实体属性与数据库字段映射时,应使用包装类型,而不是基本类型;否则会被忽略。** 如果某个字段不参与映射,可以在属性上加 `@Transient`。
### 5.4 定义 Repository 接口
```java
public interface StudentDBService extends org.fastquery.core.Repository {
@Query("select no, name, sex from student")
JSONArray findAll();
@Query("select no,name,sex,age,dept from student")
Student[] find();
}
```
### 5.5 获取并调用
```java
public class StudentDBServiceTest {
// 获取实现类
private static StudentDBService studentDBService = FQuery.getRepository(StudentDBService.class);
@Test
public void test() {
// 调用 findAll 方法
JSONArray jsonArray = studentDBService.findAll();
// 调用 find 方法
Student[] students = studentDBService.find();
}
}
```
需要特别说明:
1. **不要手动实现 Repository 接口**
2. `FQuery.getRepository(...)` 返回的实例是单例且不可变的
在 FastQuery 中,接口的实现类由框架在**项目启动阶段自动生成**。在生成过程中,框架会对接口方法进行静态分析,包括:
- SQL 语句是否合法
- 参数绑定是否正确
- 返回值类型是否匹配
- 是否正确使用分页等特性
如果存在问题,应用将无法启动,并在开发阶段直接报错,从而避免将错误带入运行期。这种设计将大量运行期校验前移到初始化阶段,在保证安全性的同时,也提升了运行时性能。
从使用角度来看,开发者只需定义接口和 SQL,无需关注底层实现细节。框架会自动完成 SQL 执行和结果映射,使代码更加简洁、低耦合。
这种基于接口的编程方式,使系统更容易扩展,同时减少人为实现带来的错误风险。
## 6. 配置文件
### 6.1 配置文件位置
默认情况下,FastQuery 会从 `classpath` 目录加载配置文件。
你也可以通过以下方式自定义配置目录:
```java
System.setProperty("fastquery.config.dir", "/data/fastquery/configs");
```
该设置会覆盖 `classpath` 中的同名配置文件。
如果项目以 JAR 方式启动,可以通过 JVM 参数指定:
```bash
java -Dfastquery.config.dir=/data/fastquery/configs -jar Start.jar
```
------
### 6.2 连接池配置示例
FastQuery 支持多种主流连接池(如 HikariCP、c3p0、Druid),并允许**多数据源共存**。
------
#### 1)c3p0 配置示例
FastQuery 完全兼容 c3p0 官方配置:
命名:c3p0.xml
```xml
com.mysql.cj.jdbc.Driver
jdbc:mysql://localhost:3306/xk
xk
abc123
100
50
1000
...
```
------
#### 2)Druid 配置示例
命名:druid.xml
```xml
```
------
👉 支持多个连接池同时存在(例如:HikariCP + Druid)。
------
### 6.3 fastquery.json 配置说明
```json
{
"scope":[
{
"config": "hikari",
"dataSourceName": "xkdb",
"basePackages": [
"org.fastquery.example",
"org.fastquery.dao.UserInfoDBService"
]
},
{
"config": "mySQLDriver",
"dataSourceName": "world-mysql",
"basePackages": ["org.fastquery.sqlserver.dao"]
}
],
"debug": true,
"queries": ["queries/", "tpl/"],
"slowQueryTime": 50,
"convert": [
{
"sourceType": "java.lang.Integer",
"targetType": "org.fastquery.bean.Option",
"converter": "org.fastquery.bean.IntToOptionConverter"
}
]
}
```
#### 配置项说明
##### 1)scope(数据源作用域)
定义“**哪个数据源作用于哪些接口/包**”:
- `config`:连接池类型(hikari / c3p0 / druid)
- `dataSourceName`:数据源名称(可选)
- `basePackages`:作用范围(包或类)
👉 规则:
- 如果指定了 `dataSourceName` → 必须存在且正确
- 如果未指定 → 调用时必须手动指定数据源
------
##### 2)debug(调试模式)
- `true`:支持 SQL 模板热加载(无需重启)
- `false`:默认关闭
⚠️ **生产环境禁止开启**
------
##### 3)queries(SQL 模板路径)
指定 `*.queries.xml` 的扫描目录:
```json
"queries": ["queries/", "tpl/"]
```
表示:
```text
classpath/queries/
classpath/tpl/
```
------
##### 4)slowQueryTime(慢查询阈值)
- 单位:毫秒
- 超过该时间将记录警告日志
------
##### 5)convert(类型转换器)
用于自定义结果映射:
```json
{
"sourceType": "java.lang.Integer",
"targetType": "org.fastquery.bean.Option",
"converter": "xxxConverter"
}
```
------
### 6.5 关键说明
数据源的初始化流程如下:
1. 读取 `fastquery.json`
2. 解析 `scope`
3. 根据 `dataSourceName` 查找对应连接池配置
4. 创建数据源并建立映射关系
## 7. Repository 与 QueryRepository
FastQuery 中有两个内置基础接口需要理解:
### 7.1 Repository
如果你的 DAO 仅仅需要声明式的查询或更新,不需要内置 CRUD 能力,那么继承 `Repository` 就够了。它更轻量。
### 7.2 QueryRepository
如果你希望直接使用框架提供的内置方法,例如:
- 根据主键查询
- 保存实体
- 更新实体
- 保存或更新
- 批量更新
- 统计记录数
- 执行事务函数
那么应继承 `QueryRepository`。它包含若干内置函数,例如 `find`、`insert`、`save`、`saveToId`、`update`、`saveOrUpdate`、`tx`、`count` 等。
一个简单例子:
```java
public interface UserInfoDBService extends QueryRepository {
}
```
这样你就可以直接调用:
```java
UserInfo u1 = new UserInfo(36, "Dick", 23);
userInfoDBService.save(u1);
UserInfo u2 = new UserInfo(36, "Dick", null);
userInfoDBService.update(u2);
```
当实体某些属性为 `null` 时,更新时这些字段默认不会参与 `set` 运算。
## 8. `@Query`:最核心的查询入口
`@Query` 是 `FastQuery` 中最基础、最重要的注解。它的职责非常纯粹:**承载 SQL**。
### 设计说明
在 `FastQuery` 中,没有区分 `@Select`、`@Insert`、`@Update` 等多种注解,而是统一使用 `@Query`。
原因如下:
- `SQL` 本身已经具备完整语义(`SELECT` / `INSERT` / `UPDATE` / `DELETE`)
- 过多注解会增加学习成本和维护复杂度
- 统一入口可以降低接口设计复杂度
对于“写操作”(`INSERT` / `UPDATE` / `DELETE`),只需额外标注:`@Modifying` 即可。
------
### 对比说明
例如:
```java
@Query("insert into table (name) values ('Tom')")
```
相比:
```java
@Insert("insert into...")
```
👉 FastQuery 更倾向于:
- 减少注解种类
- 保持模型简单
- 将语义交给 SQL 本身
### 8.1 基本查询
```java
@Query("select no, name, sex from student")
JSONArray findAll();
```
### 8.2 带参数查询
```java
@Query("select no,name,sex,age,dept from student s where s.sex=:sex and s.age > ?1")
Student[] find(Integer age, @Param("sex") String sex);
```
`Query`中的`SQL`语句支持两类参数引用方式:
- `?1`、`?2`、`?N`:按方法参数位置绑定
- `:name`:按参数名绑定,需要配合 `@Param("name")`
当参数较多时,更推荐 `:name` 方式,因为它与顺序解耦,更利于维护。
## 9. 返回值类型
`Repository` 接口的方法支持多种返回值映射方式,用于将查询结果自动转换为目标类型。
```java
// 查询返回数组格式
@Query("select no,name,sex,age,dept from student s where s.sex=:sex and s.age > ?1")
Student[] find(Integer age,@Param("sex")String sex);
// 查询返回JSON格式
@Query("select no, name, sex from student s where s.sex=:sex and s.age > ?2")
JSONArray find(@Param("sex")String sex,Integer age);
// 查询返回List Map
@Query("select no, name, sex from student s where s.sex=?1 and s.age > :age")
List