You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JDBC Template插入带默认值的SQL Server非空列方案问询

解决方案

Spring JDBC Template本身没有专门处理这类默认值列插入的独立库函数,但Spring JDBC模块原生提供了SimpleJdbcInsert工具类,完全适配你的场景,无需手动拼接SQL,也不需要应用层维护数据库默认值逻辑。


前置修正

首先需要把Dto中的基础类型改为包装类型,否则未显式赋值时基本类型会有默认值(比如int默认是0),无法区分「用户未传值」和「用户传了0值」两种场景:

public class ProductSalesDto
{
    ...
    // 改为Integer包装类,未赋值时为null
    public Integer customerId;
    ...
}

实现步骤

  1. 初始化SimpleJdbcInsert
    在Dao层构造方法中一次性初始化插入工具,指定操作的表名即可,无需重复初始化:
@Repository
public class ProductSalesDao {
    private final SimpleJdbcInsert insertProductSales;

    // 构造注入JdbcTemplate
    public ProductSalesDao(JdbcTemplate jdbcTemplate) {
        this.insertProductSales = new SimpleJdbcInsert(jdbcTemplate)
                .withTableName("ProductSales");
        // 如果需要返回自增主键,可追加配置:.usingGeneratedKeyColumns("主键列名")
    }
}
  1. 执行插入逻辑
    插入时仅把Dto中非null的字段加入参数Map,SimpleJdbcInsert会自动生成仅包含传入字段的INSERT语句,未传入的字段自动使用数据库配置的默认值:
public void addProductSales(ProductSalesDto dto) {
    Map<String, Object> params = new HashMap<>();
    // 仅非null字段加入参数
    if (dto.customerId != null) {
        params.put("CustomerId", dto.customerId);
    }
    if (dto.totalAmount != null) {
        params.put("TotalAmount", dto.totalAmount);
    }
    // 其余列同理按规则添加
    
    // 执行插入
    insertProductSales.execute(params);
    
    // 若需要获取自增主键,改用如下代码:
    // Number key = insertProductSales.executeAndReturnKey(params);
    // int id = key.intValue();
}

优化(适配50+列的场景)

如果列数太多手动判断非null太繁琐,可以写个通用反射工具方法,自动扫描Dto所有非null字段转换为参数Map,不用逐列写判断逻辑:

// 通用Dto转参数Map方法,驼峰字段名自动转数据库大驼峰列名,可根据自己的命名规则调整
private Map<String, Object> dtoToParams(Object dto) throws IllegalAccessException {
    Map<String, Object> params = new HashMap<>();
    for (Field field : dto.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        Object value = field.get(dto);
        if (value != null) {
            // 这里按你的列名规则转换,比如小驼峰customerId转成CustomerId,或者下划线格式CUSTOMER_ID
            String columnName = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, field.getName());
            params.put(columnName, value);
        }
    }
    return params;
}

注:CaseFormat是Guava提供的命名转换工具类,不想引入Guava可以自行实现简单的驼峰转目标格式的逻辑

使用工具方法后插入逻辑可以简化为:

public void addProductSales(ProductSalesDto dto) throws IllegalAccessException {
    insertProductSales.execute(dtoToParams(dto));
}

内容的提问来源于stack exchange,提问作者mattsmith5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 14:27:04