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

标签 java orm jdbi

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

相关文章:

php - Doctrine 2. 自动生成代理

java - JPA 二级表问题

java - 在整数列表的何处搜索结果?

java - 手动设置 JDBI 的驱动程序

java - 调用构造函数后何时创建对象

java - 写入 XML 文件时出现 XMLStreamException

Java聊天程序: Client Class not working due to null pointer exception

database - DB 层成员应该是静态的还是实例的?

java - 使用@UseStringTemplate3StatementLocator时,JDBI给出错误 "ORA-00900: invalid SQL statement"

java - Android SipManager 使应用程序崩溃