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

如何在Java中使用JDBI将外键属性映射为关联对象

问题描述

现有数据库对应的POJO定义如下:

class A {
   long id; // 自增主键
   String aAttribute;
}
class B {
   long id; // 自增主键
   long aId; // 关联A类的外键
   String bAttribute;     
}

需要通过JDBI将数据库记录映射为如下形式的B类,使其包含A类的实例对象而非外键字段:

class B {
   long id; // 自增主键
   A a; // A类的实际对象
   String bAttribute;    
}
解决方案

JDBI提供两种主流方式实现这种嵌套对象映射:

方法一:使用JDBI 3+的@Join注解(推荐)

JDBI 3及以上版本支持通过注解自动处理关联映射,步骤如下:

  1. 确保使用JDBI 3.x或更高版本
  2. 定义包含A类型字段a的新B类
  3. 在DAO接口的查询方法上使用@Join注解指定关联逻辑:
import org.jdbi.v3.sqlobject.customizer.Join;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import java.util.List;

public interface BDao {
    @SqlQuery("SELECT b.id as b_id, b.b_attribute as b_bAttribute, a.id as a_id, a.a_attribute as a_aAttribute " +
              "FROM b JOIN a ON b.a_id = a.id")
    @Join(value = "a", prefix = "a_")
    List<B> findAllWithA();
}
  • SQL查询中需为两个表的字段添加区分前缀(如a_、b_),避免字段名冲突
  • @Join的prefix参数对应A类字段的前缀,JDBI会自动将匹配前缀的字段映射到A对象中

方法二:自定义RowMapper手动映射

若使用低版本JDBI或需要更灵活的控制,可自定义RowMapper手动完成映射:

  1. 实现RowMapper<B>接口:
import org.jdbi.v3.core.mapper.RowMapper;
import org.jdbi.v3.core.statement.StatementContext;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BWithARowMapper implements RowMapper<B> {
    @Override
    public B map(ResultSet rs, StatementContext ctx) throws SQLException {
        A a = new A();
        a.setId(rs.getLong("a_id"));
        a.setAAttribute(rs.getString("a_aAttribute"));
        
        B b = new B();
        b.setId(rs.getLong("b_id"));
        b.setA(a);
        b.setBAttribute(rs.getString("b_bAttribute"));
        
        return b;
    }
}
  1. 在DAO中注册并使用该RowMapper:
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.customizer.RegisterRowMapper;
import java.util.List;

@RegisterRowMapper(BWithARowMapper.class)
public interface BDao {
    @SqlQuery("SELECT b.id as b_id, b.b_attribute as b_bAttribute, a.id as a_id, a.a_attribute as a_aAttribute " +
              "FROM b JOIN a ON b.a_id = a.id")
    List<B> findAllWithA();
}

注意:无论使用哪种方式,都需要确保POJO类有对应的setter方法,或使用@ConstructorProperties注解,让JDBI能正确实例化并赋值对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 22:55:16