查询多对多jpa
Query Many-to-many jpa
我需要在 @QUERY
中实现具有多对多关系的 SELECT
。也许我误解了文档中写的信息。
我的查询如下所示:
@Query("select massages.id from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1")
List<MasageEntity> findMassagesIdByStringId(@Param("strings_id") long strings_id);
在我的示例中,我使用 table 个名称。名称下划线表示错误(未经编译)。也许我应该使用实体。那么如何处理多对多关系呢?
我将展示我的实体的一部分。
我有两个实体。 MasageEntity
和 RstringEntity
.
//MasageEntity
@Entity
@Table(name = "massages")
public class MasageEntity {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "string_text")
private String string_text;
@Column(name = "string_speed")
private Long string_speed;
@Column(name = "string_color_type")
private Long string_color_type;
@Column(name = "string_color")
private String string_color;
@Column(name = "string_timing_type")
private String string_timing_type;
@Column(name = "string_timing")
private String string_timing;
@Column(name = "showed")
private Long showed;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "string_massage",
joinColumns = { @JoinColumn(name = "massage_id") },
inverseJoinColumns = { @JoinColumn(name = "string_id") })
//RstringEntity
@Entity
@Table(name = "string")
public class RstringsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name="code")
private String code;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, mappedBy = "strings")
@JsonIgnore
private Set<MasageEntity> masagess = new HashSet<>();
public RstringsEntity() {}
在 Spring Boot: native SQL 和 JPQL 中执行查询有多种方法。
在本机查询的情况下,我们使用纯 SQL 语言,在数据库级别定义查询。
在 Java 持久性查询语言 (JPQL) 的情况下,我们通过实体对象定义查询。
方案一,原生查询
您在存储库中创建了本机查询,但要使用它,我们需要将其标记为 SQL nativeQuery = true
。框架需要了解您使用的是什么查询语言。 @Query
注解默认使用 JPQL,所以这就是你出错的原因。
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID via native query
@Query(value = "select massages.* from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1", nativeQuery = true)
List<MassageEntity> findMassagesByStringIdNativeSQL(@Param("strings_id") long strings_id);
//find Message IDs by String ID via native query
@Query(value = "select massages.id from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1", nativeQuery = true)
List<Long> findMassagesIdByStringIdNativeSQL(@Param("strings_id") long strings_id);
}
方案二、JPQL查询
示例如何为您的案例定义 JPQL 查询。 JPQL 将在执行期间转换为 SQL。
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID via JPQL
@Query("select message from MassageEntity message join message.strings string where string.id = :strings_id")
List<MassageEntity> findMassagesByStringIdJPQL(@Param("strings_id") long strings_id);
//find Message IDs by String ID via JPQL
@Query("select message.id from MassageEntity message join message.strings string where string.id = :strings_id")
List<Long> findMassagesIDByStringIdJPQL(@Param("strings_id") long strings_id);
}
Hibernate 生成的本机查询:
select
massageent0_.id as id1_3_,
massageent0_.string_text as string_t2_3_
from
massages massageent0_
inner join
string_massage strings1_
on massageent0_.id=strings1_.massage_id
inner join
string rstringsen2_
on strings1_.string_id=rstringsen2_.id
where
rstringsen2_.id=?
方案三,Spring auto-generated queries
Spring 可以 auto-generate 通过存储库方法定义进行查询。
您的案例示例:
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID
List<MassageEntity> findByStrings_Id(@Param("id") long strings_id);
}
我在解决方案中使用的条目:
@Entity
@Table(name = "massages")
public class MassageEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "string_text")
private String string_text;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "string_massage",
joinColumns = { @JoinColumn(name = "massage_id") },
inverseJoinColumns = { @JoinColumn(name = "string_id") })
private Set<RstringsEntity> strings = new HashSet<>();
}
@Entity
@Table(name = "string")
public class RstringsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "code")
private String code;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, mappedBy = "strings")
@JsonIgnore
private Set<MassageEntity> massages = new HashSet<>();
}
我需要在 @QUERY
中实现具有多对多关系的 SELECT
。也许我误解了文档中写的信息。
我的查询如下所示:
@Query("select massages.id from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1")
List<MasageEntity> findMassagesIdByStringId(@Param("strings_id") long strings_id);
在我的示例中,我使用 table 个名称。名称下划线表示错误(未经编译)。也许我应该使用实体。那么如何处理多对多关系呢?
我将展示我的实体的一部分。
我有两个实体。 MasageEntity
和 RstringEntity
.
//MasageEntity
@Entity
@Table(name = "massages")
public class MasageEntity {
@Id
@GeneratedValue (strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "string_text")
private String string_text;
@Column(name = "string_speed")
private Long string_speed;
@Column(name = "string_color_type")
private Long string_color_type;
@Column(name = "string_color")
private String string_color;
@Column(name = "string_timing_type")
private String string_timing_type;
@Column(name = "string_timing")
private String string_timing;
@Column(name = "showed")
private Long showed;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "string_massage",
joinColumns = { @JoinColumn(name = "massage_id") },
inverseJoinColumns = { @JoinColumn(name = "string_id") })
//RstringEntity
@Entity
@Table(name = "string")
public class RstringsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name="code")
private String code;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, mappedBy = "strings")
@JsonIgnore
private Set<MasageEntity> masagess = new HashSet<>();
public RstringsEntity() {}
在 Spring Boot: native SQL 和 JPQL 中执行查询有多种方法。
在本机查询的情况下,我们使用纯 SQL 语言,在数据库级别定义查询。
在 Java 持久性查询语言 (JPQL) 的情况下,我们通过实体对象定义查询。
方案一,原生查询
您在存储库中创建了本机查询,但要使用它,我们需要将其标记为 SQL nativeQuery = true
。框架需要了解您使用的是什么查询语言。 @Query
注解默认使用 JPQL,所以这就是你出错的原因。
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID via native query
@Query(value = "select massages.* from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1", nativeQuery = true)
List<MassageEntity> findMassagesByStringIdNativeSQL(@Param("strings_id") long strings_id);
//find Message IDs by String ID via native query
@Query(value = "select massages.id from massages join string_massage on massages.id = string_massage.massage_id where string_massage.string_id = ?1", nativeQuery = true)
List<Long> findMassagesIdByStringIdNativeSQL(@Param("strings_id") long strings_id);
}
方案二、JPQL查询
示例如何为您的案例定义 JPQL 查询。 JPQL 将在执行期间转换为 SQL。
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID via JPQL
@Query("select message from MassageEntity message join message.strings string where string.id = :strings_id")
List<MassageEntity> findMassagesByStringIdJPQL(@Param("strings_id") long strings_id);
//find Message IDs by String ID via JPQL
@Query("select message.id from MassageEntity message join message.strings string where string.id = :strings_id")
List<Long> findMassagesIDByStringIdJPQL(@Param("strings_id") long strings_id);
}
Hibernate 生成的本机查询:
select
massageent0_.id as id1_3_,
massageent0_.string_text as string_t2_3_
from
massages massageent0_
inner join
string_massage strings1_
on massageent0_.id=strings1_.massage_id
inner join
string rstringsen2_
on strings1_.string_id=rstringsen2_.id
where
rstringsen2_.id=?
方案三,Spring auto-generated queries
Spring 可以 auto-generate 通过存储库方法定义进行查询。
您的案例示例:
@Repository
public interface MessageRepository extends JpaRepository<MassageEntity, Long> {
//find MessageEntities by String ID
List<MassageEntity> findByStrings_Id(@Param("id") long strings_id);
}
我在解决方案中使用的条目:
@Entity
@Table(name = "massages")
public class MassageEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "string_text")
private String string_text;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
@JoinTable(name = "string_massage",
joinColumns = { @JoinColumn(name = "massage_id") },
inverseJoinColumns = { @JoinColumn(name = "string_id") })
private Set<RstringsEntity> strings = new HashSet<>();
}
@Entity
@Table(name = "string")
public class RstringsEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "code")
private String code;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, mappedBy = "strings")
@JsonIgnore
private Set<MassageEntity> massages = new HashSet<>();
}