Sql 如何在Spring Boot中从双向表关系生成DTO
早上好,很高兴见到你 我最近刚接触Spring Boot,我正在使用REST API,它基本上是一个包含歌曲的播放列表,基本上REST API应该具有以下结构。一个播放列表可以有许多歌曲:Sql 如何在Spring Boot中从双向表关系生成DTO,sql,json,spring-boot,hibernate,jpa,Sql,Json,Spring Boot,Hibernate,Jpa,早上好,很高兴见到你 我最近刚接触Spring Boot,我正在使用REST API,它基本上是一个包含歌曲的播放列表,基本上REST API应该具有以下结构。一个播放列表可以有许多歌曲: { "name": "Lista 1", "description": "Lista de reproduccion 2020 spotify", "songs": [
{
"name": "Lista 1",
"description": "Lista de reproduccion 2020 spotify",
"songs": [
{
"title": "Tan Enamorados",
"artist": "CNCO",
"album": "Tan Enamorados",
"year": 2020,
"playList": 1
},
{
"title": "Hawai",
"artist": "Maluma",
"album": "PAPI JUANCHO",
"year": 2020,
"playList": 1
}
]
}
目前,这是我配置实体的方式
实体歌曲
@Entity
@Table(name = "SONGS")
public class Songs{
@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "ID")
private Long id;
@Column(name = "title")
private String title;
@Column(name = "artist")
private String artist;
@Column(name = "album")
private String album;
@Column(name = "year")
private int year;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PLAY_LIST_ID")
private PlayList playList;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return this.title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return this.artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbum() {
return this.album;
}
public void setAlbum(String album) {
this.album = album;
}
public int getYear() {
return this.year;
}
public void setYear(int year) {
this.year = year;
}
public PlayList getPlayList() {
return this.playList;
}
public void setPlayList(PlayList playList) {
this.playList = playList;
}
}
实体播放列表
@Entity
@Table(name = "PLAY_LIST")
public class PlayList {
@JsonIgnore
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "ID")
private Long id;
@Column(name="name")
private String name;
@Column(name="description")
private String description;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "playList")
private List<Songs> songs = new ArrayList<>();
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public List<Songs> getSongs() {
return this.songs;
}
public void setSongs(List<Songs> songs) {
this.songs = songs;
}
}
这是由于歌曲实体中的playList字段,当尝试获取包含歌曲的播放列表时,我会得到一个递归数组,而不是播放列表的id,这是我想要得到的,实际情况是,我得到了如下内容:
我可以通过在字段中应用JsonIgnore来解决问题,但是这会影响我,当我去保存播放列表时,我无法将idPlayList字段传递给每首歌曲,以确保每首歌曲都与其各自的idPlayList一起保存
我认为最好的办法是在这里建立一个DTO,帮助我建立两个表之间的关系,但是,我不知道如何才能做到这一点,在执行播放列表的get时,只获取idPlayList,在省电时,将idPlayList传递到将与播放列表一起保存的每首歌曲中,或者,如果有另一种方式,我可以存储一个播放列表及其歌曲,并将其直接存储,因为目前我必须由BD为每首歌曲分配idPlayList
spring.jpa.open in view=false
添加到application.properties
中,使其具有LazyInitializationException
。这将有助于构建良好的查询。
播放列表
和歌曲
,使用左连接获取
来获取列表中的歌曲。因此,歌曲
将已加载,歌曲中的播放列表
将延迟<代码>@EntityGraph也可以使用
select list from PlayList list left join fetch list.songs where list.id = :listId
hibernate5模块
。它允许省略惰性关联。因此,杰克逊不会触碰歌曲中的播放列表。
播放响应
,歌曲响应
类,并将实体映射到服务级别上的这些类。在这种情况下,您可能不需要Hibernate5Module
。但最好也尝试一下这个模块
application.properties
@Transient
public void addSong(Song song) {
song.setPlayList(this);
songs.add(song);
}
使用addSong()
方法将歌曲添加到列表中
保存播放列表。Hibernate将使用正确的列表id保存列表中的所有歌曲,因为存在
cascade=CascadeType。在@OneToMany
公共类歌曲中的所有歌曲必须是Song
。这是一条记录,不是所有的记录:)谢谢你的回答,你能给我一个左连接提取的例子吗?如果您可以将播放列表与他们的歌曲进行映射。@CesarJusto I updatedI一直在阅读@EntityGraph,这非常好,因为它可以提高查询的性能,但是,我仍然不明白如何加载(插入)包含歌曲的播放列表,由于播放列表的id是自动生成和自动递增的,因此我不知道如何将其关联,以便将歌曲与其id_播放列表值一起保存,从而保持与播放列表的关联playList@CesarJusto我更新了Hanks,我将测试更改,我会告诉你
@Repository
public interface PlayListRepository extends JpaRepository<PlayList, Long> {
Optional<PlayList> findById(Long Id);
}
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.example.api.songs.entity.PlayList[\"songs\"]->org.hibernate.collection.internal.PersistentBag[0]->com.example.api.songs.entity.Songs[\"playList\"]->com.example.api.songs.entity.PlayList[\"songs\"]->org.hibernate.
select list from PlayList list left join fetch list.songs where list.id = :listId
logging.level.org.springframework.transaction.interceptor=TRACE
logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG
logging.level.org.hibernate.SQL=DEBUG
spring.jpa.properties.hibernate.use_sql_comments=true
@Transient
public void addSong(Song song) {
song.setPlayList(this);
songs.add(song);
}