繁体   English   中英

为什么 JDBI 3 @ColumnName 注释不起作用?

[英]Why JDBI 3 @ColumnName annotation doesn't work?

我想使用 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;

爪哇豆:

@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 有一种非常丑陋的方式来为 getter 或 setter 指定注释:

@NotNull
@Getter(onMethod=@__(@ColumnName("business_system")))
private Integer businessSystem;

@NotNull
@Getter(onMethod=@__(@ColumnName("functional")))
private Integer functional;

第三, bindBean()根据 bean 属性名称绑定命名参数,而不是列名称。 所以你的命名参数应该在: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注释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM