谁能在hibernate中解释mappedBy?

bra*_*ter 165 java hibernate hibernate-mapping java-ee

我是hibernate的新手,需要使用一对多和多对一的关系.它是我对象中的双向关系,因此我可以从任一方向遍历.mappedBy是推荐的方法,但是,我无法理解.有人能解释一下:

  • 推荐的使用方法是什么?
  • 它解决了什么目的?

为了我的例子,这里是我的带注释的类:

  • Airline OWNS很多 AirlineFlights
  • 很多都 AirlineFlights属于ONE Airline

航空公司:

@Entity 
@Table(name="Airline")
public class Airline {
    private Integer idAirline;
    private String name;

    private String code;

    private String aliasName;
    private Set<AirlineFlight> airlineFlights = new HashSet<AirlineFlight>(0);

    public Airline(){}

    public Airline(String name, String code, String aliasName, Set<AirlineFlight> flights) {
        setName(name);
        setCode(code);
        setAliasName(aliasName);
        setAirlineFlights(flights);
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="IDAIRLINE", nullable=false)
    public Integer getIdAirline() {
        return idAirline;
    }

    private void setIdAirline(Integer idAirline) {
        this.idAirline = idAirline;
    }

    @Column(name="NAME", nullable=false)
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = DAOUtil.convertToDBString(name);
    }

    @Column(name="CODE", nullable=false, length=3)
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = DAOUtil.convertToDBString(code);
    }

    @Column(name="ALIAS", nullable=true)
    public String getAliasName() {
        return aliasName;
    }
    public void setAliasName(String aliasName) {
        if(aliasName != null)
            this.aliasName = DAOUtil.convertToDBString(aliasName);
    }

    @OneToMany(fetch=FetchType.LAZY, cascade = {CascadeType.ALL})
    @JoinColumn(name="IDAIRLINE")
    public Set<AirlineFlight> getAirlineFlights() {
        return airlineFlights;
    }

    public void setAirlineFlights(Set<AirlineFlight> flights) {
        this.airlineFlights = flights;
    }
}
Run Code Online (Sandbox Code Playgroud)

AirlineFlights:

@Entity
@Table(name="AirlineFlight")
public class AirlineFlight {
    private Integer idAirlineFlight;
    private Airline airline;
    private String flightNumber;

    public AirlineFlight(){}

    public AirlineFlight(Airline airline, String flightNumber) {
        setAirline(airline);
        setFlightNumber(flightNumber);
    }

    @Id
    @GeneratedValue(generator="identity")
    @GenericGenerator(name="identity", strategy="identity")
    @Column(name="IDAIRLINEFLIGHT", nullable=false)
    public Integer getIdAirlineFlight() {
        return idAirlineFlight;
    }
    private void setIdAirlineFlight(Integer idAirlineFlight) {
        this.idAirlineFlight = idAirlineFlight;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="IDAIRLINE", nullable=false)
    public Airline getAirline() {
        return airline;
    }
    public void setAirline(Airline airline) {
        this.airline = airline;
    }

    @Column(name="FLIGHTNUMBER", nullable=false)
    public String getFlightNumber() {
        return flightNumber;
    }
    public void setFlightNumber(String flightNumber) {
        this.flightNumber = DAOUtil.convertToDBString(flightNumber);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

数据库架构:

AirlineFlights的idAirline为ForeignKey,航空公司没有idAirlineFlights.这使得AirlineFlights成为所有者/识别实体?

从理论上讲,我希望航空公司成为航空公司的所有者.

在此输入图像描述

Kur*_*ois 275

MappedBy信号休眠,关系的关键在另一边.

这意味着虽然您将两个表链接在一起,但这些表中只有一个对另一个表有外键约束.MappedBy允许您仍然从不包含约束的表链接到另一个表.

  • 这应该是公认的答案. (29认同)
  • 因为有时候把钥匙放在两边都没有意义.比如说你有一家公司和一家便携式公司.便携式设备只属于一家公司,但公司将拥有多个便携式设备. (6认同)
  • 你能澄清一下吗? (3认同)

Aff*_*ffe 142

通过@JoinColumn在两个模型上指定,您没有双向关系.你有两个单向关系,并且有一个非常令人困惑的映射.你告诉两个模型他们"拥有"IDAIRLINE专栏.实际上只有其中一个真的应该!'正常'的事情是完全@JoinColumn偏离@OneToMany一边,而是将mappedBy添加到@OneToMany.

@OneToMany(cascade = CascadeType.ALL, mappedBy="airline")
public Set<AirlineFlight> getAirlineFlights() {
    return airlineFlights;
}
Run Code Online (Sandbox Code Playgroud)

这告诉Hibernate"在我找到配置的东西上查看名为'airline'的bean属性."

  • 是的,这很重要.mappedBy中的名称告诉Hibernate在哪里可以找到JoinColumn的配置.(在AirlineFlight的getAirline()方法上.)你将JoinColumn映射到航空公司的方式,你告诉航空公司它*负责维护另一个表中的值.可以告诉实体它"拥有"不同表中的列,并负责更新它.这不是您通常想要做的事情,并且可能导致执行SQL语句的顺序出现问题. (8认同)
  • 最后你对mappedBy的描述让我有点困惑。在 db 中如何组织事物是否重要?@DB:AirlineFlights 将 idAirline 作为外键。航空公司仅将 idAirline 作为主键,并不包含有关 AirlineFlights @ DB 的信息。 (2认同)

Vla*_*cea 24

表关系与实体关系

在关系数据库系统中,one-to-many表关系如下所示:

一对多表关系

请注意,该关系基于post_id子表中的外键列(例如,)。

因此,在管理one-to-many表关系时,只有一个事实来源。

现在,如果您采用映射到one-to-many我们之前看到的表关系的双向实体关系:

双向一对多实体关联

如果你看一下上面的图表,你会发现有两种方法可以管理这种关系。

Post实体中,您有以下comments集合:

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

并且,在 中PostCommentpost关联映射如下:

@ManyToOne(
    fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Run Code Online (Sandbox Code Playgroud)

因为有两种方式来表示外键列,所以在将关联状态更改转换为其等效的外键列值修改时,您必须定义哪个是真实来源。

映射者

mappedBy属性告诉@ManyToOne一侧负责管理外键列,集合仅用于获取子实体并将父实体状态更改级联到子实体(例如,删除父实体也应删除子实体)。

同步双向关联的双方

现在,即使您定义了mappedBy属性并且子端@ManyToOne关联管理了外键列,您仍然需要同步双向关联的双方。

最好的方法是添加这两个实用方法:

public void addComment(PostComment comment) {
    comments.add(comment);
    comment.setPost(this);
}

public void removeComment(PostComment comment) {
    comments.remove(comment);
    comment.setPost(null);
}
Run Code Online (Sandbox Code Playgroud)

addCommentremoveComment方法确保双方是同步的。因此,如果我们添加子实体,则子实体需要指向父实体,并且父实体应该将子实体包含在子集合中。


Cha*_* DZ 19

mappedby它说它自己,它告诉hibernate不映射这个字段它已经准备好由这个字段[name ="field"]映射.
字段在另一个实体中(name of the variable in the class not the table in the database)..

如果你不这样做,那么hibernate将映射这两个关系,因为它不是同一个关系

所以我们需要告诉hibernate只在一侧进行映射并在它们之间进行协调.

  • 也许hibernate并不总是说话本身,但是当它发生时,至少它使用标点符号 (2认同)
  • 对我来说,它本身并不说明问题;反之,则很混乱。只需看看关于“mappedBy”和“inversedBy”实际是什么的问题数量。其他 ORM 使用更智能的“belongsToMany”、“hasMany”属性。 (2认同)

小智 10

mappedby ="在另一个类中创建的同一个类的实体的对象"

注意:-Mapped只能在一个类中使用,因为一个表必须包含外键约束.如果映射的可以应用于两侧,那么它从两个表中删除外键并且没有外键与b/w两个表没有关系.

注意: - 它可用于以下注释: - 1. @ OneTone 2. @ OneToMany 3. @ ManyToMany

注意---它不能用于以下注释: - 1. @ ManyToOne

在一对一中: - 在映射的任何一侧执行,但仅在一侧执行.它将删除应用它的类的表上的额外外键约束列.

例如.如果我们在员工对象的Employee类中应用映射,那么将删除Employee表中的外键.