Skip to content
nfwork edited this page Apr 29, 2026 · 16 revisions

Context

  • 用于定义请求上下文和参数传递,是 model 执行时读取参数、写入返回参数的主要入口。

属性

修饰符和类型 Field 描述
public final HttpServletRequest request 当前请求对象
public final HttpServletResponse response 当前响应对象
private int pageLimit 查询的分页大小
private long pageStart 查询的分页游标
private final Map<String, Object> rootDatas 所有参数空间的根数据
private Map<String, Object> paramDatas request parameter 参数
private Map<String, Object> requestDatas request attribute 参数
private Map<String, Object> sessionDatas session 参数
private Map<String, Object> cookieDatas cookie 参数
private Map<String, Object> headerDatas header 参数
private Map<String, Object> outParamDatas 自定义 outParam 返回参数,通常由 modelquery/execute 返回设置

方法

修饰符和类型 方法 描述
public static Context getCurrentContext(HttpServletRequest request, HttpServletResponse response) 获取当前请求的 Context
public Object getData(String express) 根据 EL 表达式路径获取参数。参数空间包括:paramrequestsessionoutParamcookieheader
public T getData(String express, Class class1) 获取参数并转换为指定类型
public String getString(String express) 获取参数并转换为 String
类似方法还有:getIntgetLonggetFloatgetDoublegetBooleangetMapgetList
public Map<String, Object> getDatas() 获取 rootDatas
类似方法还有:getParamDatasgetRequestDatasgetOutParamDatasgetSessionDatasgetCookieDatasgetHeaderDatas
public void setData(String name, Object object) 设置参数到指定路径中;
类似方法还有:setParamDatasetOutParamDatasetRequestDatasetSessionData
public void addCookie(Param param) 在响应中添加 cookie
public Context withParam("user_name", userName) 设置单个 param 参数,支持链式调用
public Context withBeanParam(user) 使用 JavaBean 构建 Context 参数,将 Bean 属性逐一放入 param
public Context withMapParam(map) 使用 Map 构建 Context 参数,将 Map 的所有键值对放入 param
// 使用 with 方法构建 Context(从 3.6.2 开始支持)
Context context = new Context()
        .withParam("user_code", userCode)
        .withParam("user_name", userName)
        .withBeanParam(user) // 使用 JavaBean 构建 Context 参数
        .withMapParam(map) // 使用 Map 构建 Context 参数
        .withPageStart(start) // 设置分页参数 start
        .withPageLimit(limit); // 设置分页参数 limit
return modelExecutor.query(context, "user", "");


// 从当前请求的 Context 中获取参数
Object userId = context.getData("param.user_id");
// 使用 getInt 转换类型
Integer userId = context.getInt("param.user_id");

// 设置参数到 paramDatas 中
context.setData("param.user_id", userId);
// 或
context.setParamData("user_id", userId);

// 设置返回参数,适合需要额外返回业务字段的场景
context.setOutParamData("trace_id", traceId);

ModelEngine

  • 用于执行 model,适用于非 Spring 项目。
  • query 返回对象默认支持数据库字段下划线转 JavaBean 驼峰属性。特殊场景可在实体类字段上使用 @Columncom.nfwork.dbfound.model.reflector)指定映射字段名。

方法

修饰符和类型 方法 描述
public static QueryResponseObject query(Context context,
String modelName,
String queryName,
String currentPath,
boolean autoPaging,
Class clazz)
查询方法
- currentPath:指定 model 读取参数的当前路径(默认为 param
- autoPaging:是否启用分页(默认为 true;如果 context 中未设置分页参数,则不会分页)
- clazz:指定返回类型(默认为 Map<String,Object>
- 注:有重载方法可省略 currentPathautoPagingclazz 参数
public static ResponseObject batchExecute(Context context,
String modelName,
String executeName,
String sourcePath)
批量执行操作
- sourcePath:批量执行时数组参数所在路径(默认为 param.GridData
- 此方法本质上是逐条循环执行,不具备 SQL 批处理能力。大量数据批处理建议使用 model api 中的 batchExecuteSql
- 注:有重载方法可省略 sourcePath 参数
public static ResponseObject execute(Context context,
String modelName,
String executeName,
String currentPath)
执行操作
- currentPath:指定当前参数路径(默认为 param
- 注:有重载方法可省略 currentPath 参数

代码示例

// 返回内容为 Map 的 Response(数据 + 总行数)
QueryResponseObject<Map<String,Object>> r1 = ModelEngine.query(context, "user", "");
// 返回内容为 User 对象的 Response(数据 + 总行数)
QueryResponseObject<User> r2 = ModelEngine.query(context, "user", "", User.class);

// 以 Map 格式返回一行记录
Map<String,Object> map = ModelEngine.queryOne(context, "user", "");
// 以 User 对象返回一行记录
User user = ModelEngine.queryOne(context, "user", "",User.class);

// 以 List<Map> 格式返回数据
List<Map<String,Object>> list = ModelEngine.queryList(context, "user", "");
// 以 List<User> 对象返回数据
List<User> users = ModelEngine.queryList(context, "user", "",User.class);

// 修改数据
ResponseObject responseObject = ModelEngine.execute(context, "user", "update");
  • 注意:dbfound 查询支持数据库字段自动映射到 JavaBean 驼峰属性。例如数据库字段为 user_idJava 字段为 userId 时,无需额外配置。dbfound.system.underscore-to-camel-case 只控制返回 Map 类型时是否将下划线转换为驼峰,与 JavaBean 对象映射无关。

ModelExecutor

  • dbfound-spring-boot-starter 中的执行类,适用于 Spring Boot 项目,可代替 ModelEngine
  • Spring 容器管理,并支持 Spring 事务。
  • query 返回对象默认支持数据库字段下划线转 JavaBean 驼峰属性。特殊场景可在实体类字段上使用 @Columncom.nfwork.dbfound.model.reflector)指定映射字段名。

方法

修饰符和类型 方法 描述
public ResponseObject execute(Context context, String modelName,
String executeName, String currentPath)

execute(String modelName, String executeName,
Object param)
execute 方法用于执行 execute 标签
- currentPath:指定当前参数路径
- param:直接传入参数对象
- 注:有重载方法,可省略 currentPath 参数(默认为 param
- 注:contextparam 传其一即可
public ResponseObject batchExecute(Context context, String modelName,
String executeName, String currentPath)

batchExecute(String modelName, String executeName,
List<?> dataList)
batchExecute 方法用于批量执行 execute 标签
- currentPath:指定批量执行的数组参数路径
- dataList:直接传入待遍历的数据列表
- 注:有重载方法,可省略 currentPath 参数(默认为 param.GridData
- 注:contextdataList 传其一即可
- 此方法本质上是逐条循环执行,不具备 SQL 批处理能力。大量数据批处理建议使用 model api 中的 batchExecuteSql
public <T> List<T> queryList(Context context, String modelName,
String queryName, Class<T> class1)

queryList(String modelName, String queryName,
Object param, Class<T> class1)
queryList 方法用于执行 query 标签,并返回 List
- class1:指定返回类型
public <T> T queryOne(Context context, String modelName,
String queryName, Class<T> class1)

queryOne(String modelName, String queryName,
Object param, Class<T> class1)
queryOne 方法用于执行 query 标签,并返回单个实体对象
- class1:指定返回类型
public <T> QueryResponseObject<T> query(Context context, String modelName,
String queryName, String currentPath,
boolean autoPaging, Class<T> class1)

query(String modelName, String queryName,
Object param, int start, int limit, Class<T> class1)
query 方法用于执行 query 标签,并返回 QueryResponseObject
- class1:指定返回类型

代码示例

// 返回内容为 Map 的 Response(数据 + 总行数)
QueryResponseObject<Map<String,Object>> r1 = modelExecutor.query(context, "user", "");
// 返回内容为 User 对象的 Response(数据 + 总行数)
QueryResponseObject<User> r2 = modelExecutor.query(context, "user", "", User.class);

// 以 Map 格式返回一行记录
Map<String,Object> map = modelExecutor.queryOne(context, "user", "");
// 以 User 对象返回一行记录
User user = modelExecutor.queryOne(context, "user", "",User.class);

// 以 List<Map> 格式返回数据
List<Map<String,Object>> list = modelExecutor.queryList(context, "user", "");
// 以 List<User> 对象返回数据
List<User> users = modelExecutor.queryList(context, "user", "",User.class);

// 修改数据
ResponseObject responseObject = modelExecutor.execute(context, "user", "update");
  • 注意:dbfound 查询支持数据库字段自动映射到 JavaBean 驼峰属性。例如数据库字段为 user_idJava 字段为 userId 时,无需额外配置。dbfound.system.underscore-to-camel-case 只控制返回 Map 类型时是否将下划线转换为驼峰,与 JavaBean 对象映射无关。

ResponseObject

  • model execute 的响应实体对象,用于表示执行是否成功、响应消息以及返回参数。
  • 通过 ModelEngineModelExecutor 调用 queryexecute 方法时,如果能正常返回 ResponseObjectQueryResponseObject,通常就表示执行成功。执行失败一般会直接抛出异常,因此返回对象中的 success 通常不会为 false
  • 因此,在 Java API 调用场景中,一般不需要通过 response.getSuccess() == false 判断执行失败;失败逻辑建议使用异常处理。
修饰符和类型 Field 描述
private boolean success 请求是否成功
private String message 响应描述
private String code 响应码
private Map<String,Object> outParam 返回参数,在 model 中将 paramioType 设置为 outscope 设置为 outParam,返回值会自动填入此字段
ResponseObject response = modelExecutor.execute(context, "user", "update");
Object id = response.getOutParam().get("id");

QueryResponseObject

  • 继承 ResponseObject
  • query 的响应体,除通用响应信息外,还包含查询数据和总行数。

属性

修饰符和类型 Field 描述
private boolean success 请求是否成功
private String message 响应描述
private String code 响应码
private Map<String,Object> outParam 返回参数
private List<T> datas 查询返回的数据列表
private long totalCounts 查询返回的总行数

方法

修饰符和类型 方法 描述
public T get() 获取 datas 的第一个元素
public Map<String,T> getMap(String keyProperty) datas 转换为 Map,参数为作为 key 的字段名
public Object getProperty(String propertyName) 获取 datas 第一个元素中指定字段的值
public String getString(String propertyName) 获取指定字段并转换为 String
类似方法还有:getIntgetLonggetDoublegetFloat
public List<Object> getPropertyList(String propertyName) 获取 datas 中所有元素的指定字段值
public List<String> getStringList(String propertyName) 获取字段列表并转换为 String 列表;
类似方法还有:getIntListgetLongListgetDoubleListgetFloatList
public void join(QueryResponseObject joinData,
String joinField)
合并 2 个 QueryResponseObjectdata
joinField 指定用于关联的字段名
QueryResponseObject<Map<String, Object>> response = modelExecutor.query(context, "user", "");

// 获取第一条记录
Map<String, Object> firstUser = response.get();

// 提取所有用户 ID
List<Integer> userIds = response.getIntList("user_id");

// 按 user_id 转换为 Map,便于后续快速查找
Map<String, Map<String, Object>> userMap = response.getMap("user_id");

SqlDialect

  • 用于设置数据库方言,影响 query 标签的自动分页,以及 collisionSql 标签、when 标签中条件判断 SQL 的执行方式。
  • 目前内置方言包括 MySqlOracleSqlServerInformix,默认为 MySql
  • 自定义 SqlDialect 可通过配置文件中数据库的 dialect 属性配置,例如:dialect: com.gomo.admin.dialect.PostgreSQLDialect

QueryAdapter

修饰符和类型 方法 描述
default void beforeQuery(Context context,
Map<String, Param> params)
query SQL 执行前调用,可用于补充或修改查询参数
default void beforeCount(Context context,
Map<String, Param> params,
Count count)
count SQL 执行前调用,可用于调整 count SQL
default void afterQuery(Context context,
Map<String, Param> params,
QueryResponseObject<T> responseObject)
query SQL 执行后调用,可用于加工查询结果

使用场景介绍

  • 实现 QueryAdapter 时需要填写泛型。如果不需要指定泛型,可改为实现 MapQueryAdapter,默认使用 Map
  • beforeCount 可以修改 Count SQL,适合复杂 SQL 的分页统计优化。
public class CountAdapter implements MapQueryAdapter {
 
    @Override
    public void beforeCount(Context context, Map<String, Param> params, Count count) {
        // 获取当前的 count SQL
        String countSql = count.getCountSql();
        // ... 优化 count SQL ...
        // 优化后设置新的 count SQL
        count.setCountSql(newCountSql);
    }
}
  • 可以在 beforeQuery 中修改 param 的值。
  • XML 中定义了 param 标签,或者在 SQL 中使用了对应 param 时,params 参数中就会有相应的 Param 对象。
  • 可以在 afterQuery 中修改查询结果,常见场景是补充关联数据、做字段转换或过滤结果。
@Component
public class UserQueryAdapter implements MapQueryAdapter {
 
    @Autowired
    private ModelExecutor modelExecutor;
 
 
    @Override
    public void beforeQuery(Context context, Map<String, Param> params) {
        if (params.get("type").getIntValue() == 1) {
            params.get("country").setValue("CN");
        }
    }
 
    @Override
    public void afterQuery(Context context, Map<String, Param> params, QueryResponseObject<Map<String, Object>> responseObject) {
        if (responseObject.getDatas().size() < 1) {
            return;
        }
        List<Integer> userIds = responseObject.getIntList("user_id");
        Context queryContext = new Context();
        queryContext.setParamData("userIds", userIds);
        QueryResponseObject<Map<String, Object>> userDevice = modelExecutor.query(queryContext, "user/user_device", "findByUserIds");
        responseObject.join(userDevice, "user_id");
    }
 
}

ExecuteAdapter

修饰符和类型 方法 描述
default void beforeExecute(Context context,
Map<String, Param> params)
execute SQL 执行前调用
default void afterExecute(Context context,
Map<String, Param> params)
execute SQL 执行后调用

场景介绍

  • adapterSQL 执行在同一个事务中,适合在执行前后做业务校验、记录旧值、补充联动处理等操作。
@Component
public class ConfigUpdateAdapter implements ExecuteAdapter {
 
    @Autowired
    private ModelExecutor modelExecutor;
 
    @Override
    public void beforeExecute(Context context, Map<String, Param> params) {
        GuildConfig query = modelExecutor.query("/user/guild", "findByUserId", ImmutableMap.of("user_id", params.get("user_id").getValue()), GuildConfig.class).get();
        context.request.setAttribute("oldEnableValue", query.getEnable());
    }
    @Override
    public void afterExecute(Context context, Map<String, Param> params) {
        Integer userId = params.get("user_id").getIntValue();
        GuildConfig query = modelExecutor.query("/user/guild", "findByUserId", ImmutableMap.of("user_id", userId), GuildConfig.class).get();
        Boolean enable = query.getEnable();
        Object oldEnableValue = context.request.getAttribute("oldEnableValue");
        if (enable && Objects.equals(oldEnableValue, false)) {
            // 由禁用改为启用
            // ...
        } else if (!enable && Objects.equals(oldEnableValue, true)) {
            // 由启用改为禁用
            // ...
        }
    }
}

MapQueryAdapter 和 ObjectQueryAdapter

  • 二者都继承 QueryAdapter,用于简化泛型声明。
  • MapQueryAdapter 默认将 QueryResponseObject 的数据类型设置为 Map
  • ObjectQueryAdapter 默认将 QueryResponseObject 的数据类型设置为 Object

ExcelWriter

修饰符和类型 方法 描述
public static void excelExport(Context context,
String modelName,
String queryName)
根据 model 查询结果导出 Excelcontext 需设置 param.columns 属性,
类型为 ExcelColumn 数组
public static void setExportFilename(Context context,
String filename)
设置这个 context 导出的文件名,
该文件名会设置到响应头 Content-Disposition
public static void excelExport(Context context,
List<?> dataList,
List<ExcelColumn> columns)
使用自定义数据和表头导出 Excel

介绍

static final ExcelColumn COLUMN1 = new ExcelColumn("user_id", "用户ID", 180);
static final ExcelColumn COLUMN2 = new ExcelColumn("name", "用户名", 180);
static final ExcelColumn COLUMN3 = new ExcelColumn("status", "用户状态", 160);
static final ExcelColumn COLUMN4 = new ExcelColumn("create_time", "创建时间", 180);
static final List<ExcelColumn> EXCEL_COLUMNS = Lists.newArrayList(COLUMN1, COLUMN2, COLUMN3, COLUMN4);
 
static {
    // 字段映射
    COLUMN3.setMapper(ImmutableMap.of("1", "正常", "0", "注销"));
    // 设置格式
    COLUMN4.setFormat("yyyy-MM-dd");
}
 
public void export(Context context) throws Exception {
    ExcelWriter.setExportFilename(context, "用户列表.xlsx");
    List<Map<String, Object>> result = ModelEngine.query(context, "user/user", "excel", false).getDatas();
    ExcelWriter.excelExport(context, result, EXCEL_COLUMNS);
}

ExcelReader

修饰符和类型 方法 描述
public static List<List<Map<String, Object>>> readExcel(InputStream input,
String type)
读取输入的 Excel 文件,
支持格式:xlsxlsxcsv
public static Map<String, List<Map<String, Object>>> readExcelForMap(InputStream input,
String type)
读取为 Map 格式
    // 3.6.3 后支持定义 columns 配置,避免 SQL 中需要写中文。
    // 不配置 column 时,需要写成 ${@用户账号} 获取参数;配置后可写成 ${@user_code}。
    public ResponseObject importData(FilePart filePart) {
        List<ExcelColumn> columns = Lists.newArrayList(
                new ExcelColumn("user_code", "用户账号"),
                new ExcelColumn("user_name", "用户昵称")
        );
        List<List<Map<String, Object>>> datas = ExcelReader.readExcel(filePart, columns);
        Context context = new Context().withParam("userList", datas.get(0));
        return modelExecutor.execute(context, "userExcel", "");
    }

ExcelColumn

修饰符和类型 Field 描述
private String name 映射的字段名
private String title Excel 表头
private Integer width 列宽,默认 100
private Map<String,Object> mapper 字段值和展示内容的映射;如果值中包含逗号,会自动按逗号分隔后再匹配
private String format 日期、数字等字段的展示格式

TransactionUtil

  • 一般用于非 Spring Boot 项目的事务管理;在特殊情况下不能使用事务注解时,也可以使用该工具类手动管理事务。
TransactionUtil.executeWithoutResult(context, () -> {
    ResponseObject res = ModelEngine.execute(context, "table/table_1", "add");
    // 获取自增 ID
    Integer id = Integer.parseInt(res.getOutParam().get("id").toString());
    Table2Entity entity = new Table2Entity(id);
    ModelEngine.execute("table/table_2", "add", entity);
});

Clone this wiki locally