我想使用jdbi 3 @ColumnName注释来映射表的列名和java bean字段,但在运行时jdbi抛出异常。 我的问题是为什么会抛出异常?是我的用法不正确吗?如何解决这个问题呢? 谢谢
数据库表:
CREATE TABLE `department` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL DEFAULT '' ,
`business_system` tinyint(4) NOT NULL ,
`functional` tinyint(4) NOT NULL ,
`remark` varchar(100) NOT NULL DEFAULT ''
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Java Bean:
@Data
public class Department {
private Long id;
@NotNull
@Size(min = 3, max = 20)
private String name;
@NotNull
@ColumnName("business_system")
private Integer businessSystem;
@NotNull
@ColumnName("functional")
private Integer functional;
@Max(value = 200)
private String remark;
}
JDBI 更新:
@Override
public Long create(Department department) {
String sql = "INSERT INTO department (name, business_system, functional, remark)"
+ "VALUES (:name, :business_system, :functional, :remark)";
return jdbi.withHandle(handle -> handle.createUpdate(sql)
.bindBean(department)
.executeAndReturnGeneratedKeys()
.mapTo(Long.class)
.findOnly());
}
单元测试运行结果:
org.jdbi.v3.core.statement.UnableToExecuteStatementException: Unable to
execute, no named parameter matches 'business_system'. [statement:"INSERT INTO
department (name, business_system, functional, remark)VALUES (:name,
:business_system, :functional, :remark)", rewritten:"INSERT INTO department
(name, business_system, functional, remark)VALUES (:name, :business_system,
:functional, :remark)", parsed:"ParsedSql{sql='INSERT INTO department (name,
business_system, functional, remark)VALUES (?, ?, ?, ?)',
parameters=ParsedParameters{positional=false, parameterNames=[name,
business_system, functional, remark]}}",
arguments:{ positional:{}, named:{}, finder:[{lazy bean property arguments
"Department(id=null, name=test, businessSystem=2, functional=2,
remark=test)"]}]
最佳答案
这里是 Jdbi 维护者。四种误解共同导致您的代码无法运行:
首先,@ColumnName
定义了一种单向映射,仅用于将列名称映射到对象属性/字段/构造函数参数。因此,BeanMapper
将遵循 @ColumnName
注释,但 bindBean()
会忽略它。
其次,BeanMapper
仅检测 getter 和 setter 上的 @ColumnName
,而不是字段。
由于您使用的是 Lombok 的 @Data
注释,因此 @ColumnName
注释实际上放置在字段上。 Lombok 有一种 super 丑陋的方式来指定 getter 或 setter 的注释:
@NotNull
@Getter(onMethod=@__(@ColumnName("business_system")))
private Integer businessSystem;
@NotNull
@Getter(onMethod=@__(@ColumnName("functional")))
private Integer functional;
第三,bindBean()
根据 bean 属性名称而不是列名称绑定(bind)命名参数。所以你的命名参数应该是 :camelCase
而不是 :snake_case
:
INSERT INTO department (name, business_system, functional, remark)
VALUES (:name, :businessSystem, :functional, :remark)
-- ^ camel case property name
最后,Jdbi 3 已经将蛇形命名法的列名称与驼峰式命名法的属性名称进行了开箱即用的匹配。例如:列 foo_bar
将自动映射到 fooBar
属性,无需 @ColumnName
注释。
关于java - 为什么 JDBI 3 @ColumnName 注释不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53120150/