Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何编写JPA查询_Java_Jpa_Orm_Jpql - Fatal编程技术网

Java 如何编写JPA查询

Java 如何编写JPA查询,java,jpa,orm,jpql,Java,Jpa,Orm,Jpql,学习如何编写JPA查询。请告知我是否可以在单个select语句中更有效地编写以下查询。可能是加入,但不确定如何加入 class Relationship { @ManyToOne public String relationshipType; //can be MANAGER, CUSTOMER etc @ManyToOne public Party partyFrom; // a person who has a relation @ManyToOne publ

学习如何编写JPA查询。请告知我是否可以在单个select语句中更有效地编写以下查询。可能是加入,但不确定如何加入

class Relationship {

  @ManyToOne
  public String relationshipType;  //can be MANAGER, CUSTOMER etc

  @ManyToOne
  public Party partyFrom; // a person who has a relation

  @ManyToOne
  public Party partyTo; // a group a person relate to
}
查询:

        String sql = "";
        sql = "select rel.partyTo";
        sql += " from Relationship rel";
        sql += " where rel.partyFrom = :partyFrom";
        sql += " and rel.relationshipType= :typeName";
        Query query = Organization.em().createQuery(sql);
        query.setParameter("partyFrom", mgr1);
        query.setParameter("typeName", "MANAGER");
        List<Party> orgList = query.getResultList();

        String sql2 = "";
        sql2 = "select rel.partyFrom";
        sql2 += " from Relationship rel";
        sql2 += " where rel.partyTo = :partyToList";
        sql2 += " and rel.relationshipType = :typeName2";
        Query query2 = Organization.em().createQuery(sql2);
        query2.setParameter("partyToList", orgList);
        query2.setParameter("typeName2", "CUSTOMER");
        List<Party> personList2 = query2.getResultList();
这两个查询都有效。查询1返回一个组列表,其中personmgr1有一个与的关系管理器。查询2将他们是客户的所有人员返回到查询1返回的组。实际上,我得到了一个他们属于客户组的人员列表,该客户组中的人员mgr1有一个关系经理


是否可以将它们组合到一个sql语句中,以便可能只有一个db访问?

您可以将一个查询嵌套在另一个查询中,并使用where in子句指定外部查询应从内部查询获取客户

select rel2.partyFrom
from Relationship rel2
where rel2.relationshipType = :typeName2 /* customer */
and rel2.partyTo.id in 
      (select rel.partyTo.id
      from Relationship rel
      where rel.partyFrom = :partyFrom
      and rel.relationshipType = :typeName)
调用代码像以前一样从参数中传递typeName、typeName2和Party。不需要PartyTo参数,因为数据来自子SELECT内部查询

select rel2.partyFrom
from Relationship rel2
where rel2.relationshipType = :typeName2 /* customer */
and rel2.partyTo.id in 
      (select rel.partyTo.id
      from Relationship rel
      where rel.partyFrom = :partyFrom
      and rel.relationshipType = :typeName)
使用自连接可以实现同样的效果,其中where子句在左侧过滤经理,在右侧过滤客户,但使用“in”子句在语义上更清晰


编辑:我在子选择中添加了.id,我认为这是必需的。

这不是对问题的回答,而是帮助其他人,以防有人使用JPQL在Spring Data JPA中查看@OneToMany关系,因为该问题与JPA有关,所以我想分享我的2美分,请提前道歉

@Entity
@Table(name = "MY_CAR")
public class MyCar {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "DESCRIPTION")
private String description;

@Column(name = "MY_CAR_NUMBER")
private String myCarNumber;

@Column(name = "RELEASE_DATE")
private Date releaseDate;

@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "MY_CAR_VEHICLE_SERIES", joinColumns = @JoinColumn(name = "MY_CAR_ID "), inverseJoinColumns = @JoinColumn(name = "VEHICLE_SERIES_ID"))
private Set<VehicleSeries> vehicleSeries;
public MyCar() {
    super();
    vehicleSeries = new HashSet<VehicleSeries>();
}
// set and get method goes here


@Entity
@Table(name = "VEHICLE_SERIES ")
public class VehicleSeries {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "SERIES_NUMBER")
private String seriesNumber;

@OneToMany(cascade = { CascadeType.ALL })
@JoinTable(name = "VEHICLE_SERIES_BODY_TYPE", joinColumns = @JoinColumn(name = "VEHICLE_SERIES_ID"), inverseJoinColumns = @JoinColumn(name = "BODY_TYPE_ID"))
private Set<BodyType> bodyTypes;
public VehicleSeries() {
    super();
    bodyTypes = new HashSet<BodyType>();
}
// set and get method goes here


@Entity
@Table(name = "BODY_TYPE ")
public class BodyType implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "NAME")
private String name;
// set and get method goes here


public interface MyCarRepository extends JpaRepository<MyCar, Long> {
public Set<MyCar> findAllByOrderByIdAsc();

@Query(value = "select distinct myCar from MyCar myCar "
        + "join myCar.vehicleSeries as vs join vs.bodyTypes as bt where vs.seriesNumber like %:searchMyCar% "
        + "or lower(bt.name) like lower(:searchMyCar) or myCar.bulletinId like %:searchMyCar% "
        + "or lower(myCar.description) like lower(:searchMyCar) "
        + "or myCar.bulletinNumber like %:searchMyCar% order by myCar.id asc")
public Set<MyCar> searchByMyCar(@Param("searchMyCar") String searchMyCar);
从Body_Type中选择*

ID      NAME  
1       Compact
2       Convertible 
3       Sedan

谢谢在没有id的情况下工作完美-编辑。。将接受答案,等待查看是否有人对内部查询的性能发表评论。。这是否是实现这一目标的最佳方式。。再次感谢..子查询会很快,因为它不是一个相关查询-它只计算一次,就像原始代码一样。就在今天,我用WHERE-IN替换了一个左连接,并将SQL server上的查询性能从18秒改为5秒。您不会说您使用的是哪一个数据库,但一般来说,当您只进行存在性测试而不使用任何数据时,子查询的性能会优于联接。谢谢。。计划使用PostgreSQL或Oracle。。我使用hibernate ORM,因此它也可能与其他ORM兼容。。你能详细说明一个生存测试与不使用任何数据的情况吗。。每天学习新内容:-谢谢..使用联接,通常这样做是为了从联接表中引入其他字段。有些人还使用外部联接作为一种存在性测试—该键是否存在于联接值集中。但是,由于联接表中不需要任何其他字段,因此使用WHERE IN子句效率更高。