是否需要@Bind注解?Spring Boot与普通Java项目差异解析
关于Spring Boot与普通项目中JDBI参数绑定差异的问题
问题描述
我偶然发现,在Spring Boot项目中,编写如下JDBI查询语句时无需绑定参数:
@SqlQuery(""" select id, name from organisations where id = :id """) @RegisterRowMapper(OrganisationMapper.class) Organisation getOrgansation(@Bind("id") String id);
去掉@Bind注解后仍能正常运行:
@SqlQuery(""" select id, name from organisations where id = :id """) @RegisterRowMapper(OrganisationMapper.class) Organisation getOrgansation(String id);
但将另一个非Spring Boot项目升级到3.43.0版本后,无法移除@Bind绑定。请问为何两者存在此差异?有无无需绑定的实现技巧?
差异原因
- Spring Boot的JDBI starter默认启用了参数名自动绑定功能。Spring在集成JDBI时,会自动配置
useArgumentNamesAsBindings为true,让JDBI通过反射获取方法参数的真实名称,直接匹配SQL中的:id这类同名占位符,因此不需要@Bind注解。 - 非Spring Boot的普通项目升级到JDBI 3.43.0后,默认未开启参数名自动绑定。JDBI 3.x版本中,该功能是可选配置,默认依赖
@Bind注解来关联参数与SQL占位符,所以移除注解后会出现绑定失败的问题。
无需绑定的实现技巧
1. 显式开启参数名自动绑定
在初始化JDBI实例时,配置开启useArgumentNamesAsBindings:
Jdbi jdbi = Jdbi.create(dataSource); jdbi.configure(config -> { config.setUseArgumentNamesAsBindings(true); });
开启后,JDBI会自动将方法参数名与SQL中同名的占位符绑定,无需再添加@Bind注解。
2. 编译时保留参数名称元数据
确保项目编译时保留参数名信息,否则JDBI无法通过反射获取真实参数名,只能得到arg0这类默认名称:
- 使用Java 8及以上版本时,编译需添加
-parameters参数。 - Maven项目可在
pom.xml中配置编译器插件:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
注意点
- 如果方法参数名称和SQL占位符名称不一致,即使开启自动绑定,仍需用
@Bind("占位符名称")指定对应关系。 - 部分旧版本JDK或编译环境不支持参数名反射,此时必须添加
-parameters编译参数才能让自动绑定生效。
内容的提问来源于stack exchange,提问作者Thomas Sundberg
相关产品推荐
相关产品推荐

