JOOQ pojos与一对多和多对多的关系

时间:2014-04-27 21:18:54

标签: java sql many-to-many one-to-many jooq

我正在努力了解如何使用JOOQ处理与一对多和多对多关系的pojos。

我存储由玩家创建的位置(一对多关系)。一个位置可以容纳多个可能访问它的其他玩家(多对多)。数据库布局归结为以下内容:

CREATE TABLE IF NOT EXISTS `Player` (
  `player-id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `player` BINARY(16) NOT NULL,
  PRIMARY KEY (`player-id`),
  UNIQUE INDEX `U_player` (`player` ASC))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `Location` (
  `location-id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(32) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL,
  `player-id` INT UNSIGNED NOT NULL COMMENT '
  UNIQUE INDEX `U_name` (`name` ASC),
  PRIMARY KEY (`location-id`),
  INDEX `Location_Player_fk` (`player-id` ASC),
  CONSTRAINT `fk_location_players1`
    FOREIGN KEY (`player-id`)
    REFERENCES `Player` (`player-id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `location2player` (
  `location-id` INT UNSIGNED NOT NULL,
  `player-id` INT UNSIGNED NOT NULL,
  INDEX `fk_ location2player_Location1_idx` (`location-id` ASC),
  INDEX `fk_location2player_Player1_idx` (`player-id` ASC),
  CONSTRAINT `fk_location2player_Location1`
    FOREIGN KEY (`location-id`)
    REFERENCES `Location` (`location-id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_location2player_Player1`
    FOREIGN KEY (`player-id`)
    REFERENCES `Player` (`player-id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

在我的java应用程序中,所有这些信息都存储在一个pojo中。请注意,播放器和受邀玩家列表可以在应用程序内更新,也需要在数据库中更新:

public class Location {

    private final String name;
    private UUID player;
    private List<UUID> invitedPlayers;

    public void setPlayer(UUID player) {
        this.player = player;
    }

    public void invitePlayer(UUID player) {
        invitedPlayers.add(player);
    }

    public void uninvitePlayer(UUID player) {
        invitedPlayers.remove(player);
    }

    //additional methods…
}

我可以使用JOOQ的pojo映射将这三个记录映射到单个pojo中吗?我可以使用此pojo中的JOOQ的CRUD功能来更新一对多和多对多的关系吗?如果不能使用pojo映射,除了用它来编写我的SQL语句之外,我能以任何方式利用JOOQ吗?

2 个答案:

答案 0 :(得分:5)

jOOQ尚未开箱即用这种POJO映射,但您可以利用ModelMapper之类的功能jOOQ integration,这在某种程度上适用于这些场景。

基本上,ModelMapper挂钩到jOOQ的RecordMapper API。更多细节在这里:

答案 1 :(得分:1)

您可以使用SimpleFlatMapper 查询的ResultSet。

创建一个以播放器为键的映射器

JdbcMapper<Location> jdbcMapper = 
    JdbcMapperFactory.addKeys("player").newMapper(Location.class);

然后使用fetchResultSet获取ResultSet并将其传递给mapper。 请注意,orderBy(LOCATION.PLAYER_ID)非常重要,否则您最终可能会出现拆分位置。

try (ResultSet rs = 
    dsl
        .select(
                LOCATION.NAME.as("name"), 
                LOCATION.PLAYER_ID.as("player"), 
                LOCATION2PLAYER.PLAYERID.as("invited_players_player"))
        .from(LOCATION)
            .leftOuterJoin(LOCATION2PLAYER)
                .on(LOCATION2PLAYER.LOCATION_ID.eq(LOCATION.LOCATION_ID))
        .orderBy(LOCATION.PLAYER_ID)
        .fetchResultSet()) { 
    Stream<Location> stream = jdbcMapper.stream(rs);

}

然后在流上做你需要做的事情,你也可以得到一个迭代器。