我第一次制作Spring靴。我使用的是Spring启动版本2.3.4。我也使用后格雷SQL。我想创建两个表:玩家和团队。球队应该有一个球员名单。
所以我创建了下面两个实体类:
@Entity
@Table(name = "Players")
public class Player {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="player_id")
private Long playerId;
private String name;
private int dateOfBirth;
private String originCountry;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "team_id", referencedColumnName = "team_id")
private Team team;
}
和
@Entity
@Table(name = "Teams")
public class Team{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="team_id")
private Long teamId;
private String name;
private String country;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "team", orphanRemoval = true)
private List<Player> players = new ArrayList();
}
您可能已经知道,Spring boot会自动创建表格。团队表没有球员列的问题。
这里怎么了?也许我不需要看到球队表中的球员栏?(这对我来说很奇怪……)有没有更好的方法来定义值列表或数组?
此外,我想了解:@JoinColumn(name=“team_id”)
是否定义了玩家团队属性的列名私人团队
?
谢谢!!
我认为当您考虑对象关系映射(ORM)时,您混淆了两个不同的概念。请记住,您正在使用JPA,并且在幕后使用Hibernate。一件事是您的Java
应用程序的对象,另一件事是您拥有的表集,例如,单独考虑一个多对多
关系。您可以使用2个对象轻松映射它:
class Match {
...
private Set<Team> teams;
...
}
class Team {
...
private Set<Match> matches;
...
}
这是两个对象的多对多组合。但是,如何将其映射到规范化的关系数据库上呢?在这种情况下,您需要一个交汇表
,因此您将拥有两个表以及一个team_match
表,该表将仅具有团队的id和匹配项的id,并且这两个字段都将是唯一的约束。因此,当您要获取信息时,您将使用 JOIN
,如下所示:
SELECT t.*, m.* FROM team t
JOIN team_match tm ON t.id = tm.team_id
JOIN match m ON m.id = tm.match_id
发生的事情是,框架,在本例中是Hibernate,将所有这些抽象化,将对象转换为表。而且,有时,它不会是一个对象精确到一个表。
考虑到这一点,考虑关系数据库,您将始终需要额外的表。你可以在Postgres中使用jsonb
类型来实现这一点,但在这种情况下,我不建议这样做,所以我不会写更多关于它的文章。尽管如此,我建议您更深入地阅读ORM(对象关系映射),以更好地了解幕后会发生什么。并希望答案对您有所帮助。
编辑:
好吧,对不起,你的评论让我意识到我可以告诉你实现这一目标的方法。因此,最规范的方法是这样的:
@Entity
class Team
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="team_id")
private Long teamId;
// ...
@OneToMany(mappedBy = "team", fetch = LAZY, cascade = ALL)
private List<PlayerId> players;
// ...
}
@Entity
class PlayerId {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="player_id")
private Long playerId;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "team_id", referencedColumnName = "team_id")
private Team team;
// ...
}
请注意,@OneToMore
注释引用了在目标实体中组成的对象。希望有帮助。
编辑2:
关于< code > @ join column :< code > name 是当前表/实体中的联接列,而< code > referenced column name 是外部表/实体中的联接列。
我不知道我做得是否正确,但我正在创建一个应用程序,为高中毕业舞会分配门票,对于每个学生,我让学校放入ID中,因为所有学生在该学校都有一个唯一的ID,并作为密钥存储。但问题是,不同学校的两个学生可能有相同的ID,所以我打算将主密钥存储为学生ID和学校ID。这是我的学生实体类。 beanCreationException:创建类路径资源[org/springframework/boot/autocon
问题内容: 我知道静态方法在类级别。因此,我知道我不需要创建实例来调用静态方法。但我也知道我可以将静态方法(如LIKE)称为实例方法。这是我感到困惑的地方,因为我期望从null对象调用静态方法(就像在调用实例方法中一样)。我真的很感谢一些解释,为什么我错了一个期望。 这是示例代码: 问题答案: 通过实例调用静态方法不需要实例存在。只要编译器能够确定变量的类型,它就可以在评估表达式并丢弃结果后静态进
这是我的父类,有两个名为的方法。带有参数的那个在子类中使用。 这是我的子类,在子类的方法中,我使用父类的方法: 当我尝试显示子类的对象时,我得到以下错误: 线程“main”java.lang.StackOverflowError中出现异常
我使用springboot和spring jpa作为我的后端框架。在访问jpa存储库中的实体时,我遇到了以下异常。 @Transactional注释有什么问题吗?还是因为我在两个方法中使用了相同的UserEntity?
我想用springboot和Mongo数据库对话。 它使用spring-boot-starter-data-mongoDB并自动配置默认bean,这确实允许我的MongoRepository类与DB进行对话。 但是,我想重写默认值。我可以使用application.properties,但我需要能够在应用程序启动时将连接参数作为选项在命令行上传递。 我已经尝试改变端口以破坏它,我已经将debug添