使用QueryDSL为了查询近距离点的数据库 [英] Using QueryDSL in order to query a database for close distance points

查看:746
本文介绍了使用QueryDSL为了查询近距离点的数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中有以下实体:


  • 成员

  • FamilyAdvertisment

  • 地址



成员实体中:

  @OneToOne(cascade = CascadeType.ALL)
私有地址;
...
@OneToMany(fetch = FetchType.LAZY,mappedBy =member)
private List< Advertisement>广告;

Advertisement entity:

  @NotNull 
@ManyToOne(fetch = FetchType.LAZY)
私人会员;

完整地址实体:

  @Entity 
公共类地址{

private String formattedAddress;
私人双纬度;
私人双倍经度;
}

我试图找到所有那些FamilyAdvertisement实例,地址在20KM以内。



以下是我想到的:

  QFamilyAdvertisement qFamilyAdvertisement = QFamilyAdvertisement.familyAdvertisement; 

NumberPath< Double> lat = qFamilyAdvertisement.member.address.latitude; // NPE
NumberPath< Double> lng = qFamilyAdvertisement.member.address.longitude;
NumberPath< Double>距离=空;
NumberExpression< Double>公式=
(cos(radians(Expressions.constant(requiredAddress.getLatitude())))
.multiply(cos(radians(lat))
.multiply(cos(radians( ls).subtract(radians(Expressions.constant(requiredAddress.getLongitude())))
.add(sin(radians(Expressions.constant(requiredAddress.getLatitude())))
.multiply(sin (radians(lat))))))))
.multiply(Expressions.constant(6371)));

列出<家庭广告> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20))。list(qFamilyAdvertisement);

但是,我似乎错误地使用NumberPath类,因为我一直在获取NPE。任何人都可以帮我查询我的查询吗?
$ b

edit :我已经改变了我的FamilyAdvertisement实体,如下所示:

  @NotNull 
@ManyToOne(fetch = FetchType.LAZY)
@QueryInit(地址)
私人会员会员;

现在我得到以下异常:

  java.lang.IllegalArgumentException:连接只允许使用根路径:familyAdvertisement.member.address 
com.mysema.query.DefaultQueryMetadata.ensureRoot(DefaultQueryMetadata.java:208)
com.mysema.query.DefaultQueryMetadata.validateJoin(DefaultQueryMetadata.java:132)
com.mysema.query.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:118)
com.mysema.query.DefaultQueryMetadata .addJoin(DefaultQueryMetadata.java:110)
com.mysema.query.support.QueryMixin.from(QueryMixin.java:161)
com.mysema.query.jpa.JPQLQueryBase.from(JPQLQueryBase.java :96)
com.mysema.query.jpa.impl.JPAQuery.from(JPAQuery.java:30)
org.springframework.data.jpa.repository.support.Querydsl.createQuery(Querydsl.java :88)
org.springframework.data.jpa.repository.support.QueryDslRepositorySupport.from(QueryDslRepositorySupport.java:94)
com .bignibou.repository.FamilyAdvertisementRepositoryImpl.performFamilyAdvertisementSearch(FamilyAdvertisementRepositoryImpl.java:64)

64行是这一行:

 列表<家庭广告> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20))。list(qFamilyAdvertisement); 

任何线索现在有什么不对?

edit2 :我忘了提及 FamilyAdvertisement 扩展广告,并且 member 变量位于 Advertisement 中。



edit3 strong>:这是我试图用QueryDSL重现的SQL:

  select * from family_advertisement内部联接成员m 
on a.member = m.id
其中m.address
in(
SELECT id
FROM地址其中
6371 *
acos(cos (弧度(48.8558966))
* cos(弧度(纬度))
* cos(弧度(经度) - 弧度(2.3622728))
+ sin(弧度(48.8558966))
* sin(弧度(纬度))
)<20);

我试过这样的事情:

 列表与LT; FamilyAdvertisement> (qAddress.address).where(formula.lt(20)))$ b $() b 
).list(qFamilyAdvertisement);

其中公式如上所示,但我不确定如何在QueryDSL中表示不相关的子查询,特别是在上面的运算符似乎是有问题的...

edit4

以下子查询现在可以运行:

  List< FamilyAdvertisement> (QAddress.address).where(formula.lt(20)).list(QAddress.address))中的新的JPASubQuery()。新的JPASubQuery ).LIST(qFamilyAdvertisement); 


解决方案

>

  qFamilyAdvertisement.member.address.latitude; 

请在这里阅读更多关于Querydsl http://www.querydsl.com/static/querydsl/3.1.0/reference/html/ch03s04 .html#d0e1699


I have the following entities in my application:

  • Member
  • FamilyAdvertisment
  • Address

In Member entity:

@OneToOne(cascade=CascadeType.ALL)
    private Address address;
...
@OneToMany(fetch = FetchType.LAZY, mappedBy = "member")
private List<Advertisement> advertisements;

In Advertisement entity:

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
private Member member;

Full Address entity:

@Entity
public class Address {

    private String formattedAddress;
    private double latitude;
    private double longitude;
}

I am trying to find all those FamilyAdvertisement instances whose member has an adress within 20KM of the required address.

Here is what I have come up with:

QFamilyAdvertisement qFamilyAdvertisement = QFamilyAdvertisement.familyAdvertisement;

NumberPath<Double> lat = qFamilyAdvertisement.member.address.latitude;//NPE
NumberPath<Double> lng = qFamilyAdvertisement.member.address.longitude;
NumberPath<Double> distance = null;
NumberExpression<Double> formula = 
        (acos(cos(radians(Expressions.constant(requiredAddress.getLatitude())))
        .multiply(cos(radians(lat))
        .multiply(cos(radians(lng).subtract(radians(Expressions.constant(requiredAddress.getLongitude())))
        .add(sin(radians(Expressions.constant(requiredAddress.getLatitude())))
        .multiply(sin(radians(lat))))))))
        .multiply(Expressions.constant(6371)));

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20)).list(qFamilyAdvertisement);

However, it seems that I am incorrectly using the NumberPath class as I keep getting a NPE. Can anyone please help me get my query right?

edit: I have altered my FamilyAdvertisement entity as follows:

@NotNull
@ManyToOne(fetch = FetchType.LAZY)
@QueryInit("address")
private Member member;

I now get the following exception:

java.lang.IllegalArgumentException: Only root paths are allowed for joins : familyAdvertisement.member.address
    com.mysema.query.DefaultQueryMetadata.ensureRoot(DefaultQueryMetadata.java:208)
    com.mysema.query.DefaultQueryMetadata.validateJoin(DefaultQueryMetadata.java:132)
    com.mysema.query.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:118)
    com.mysema.query.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:110)
    com.mysema.query.support.QueryMixin.from(QueryMixin.java:161)
    com.mysema.query.jpa.JPQLQueryBase.from(JPQLQueryBase.java:96)
    com.mysema.query.jpa.impl.JPAQuery.from(JPAQuery.java:30)
    org.springframework.data.jpa.repository.support.Querydsl.createQuery(Querydsl.java:88)
    org.springframework.data.jpa.repository.support.QueryDslRepositorySupport.from(QueryDslRepositorySupport.java:94)
    com.bignibou.repository.FamilyAdvertisementRepositoryImpl.performFamilyAdvertisementSearch(FamilyAdvertisementRepositoryImpl.java:64)

Line 64 is this one:

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement.member.address).where(formula.as(distance).lt(20)).list(qFamilyAdvertisement);

Any clue what is wrong now?

edit2: I forgot to mention that FamilyAdvertisement extends Advertisement and that the member variable is in Advertisement.

edit3: Here is the SQL I am trying to reproduce with QueryDSL:

select * from family_advertisement a inner join member m
on a.member = m.id
where m.address
in (
SELECT id 
FROM address where 
 6371 * 
acos( cos( radians(48.8558966) ) 
* cos( radians( latitude ) ) 
* cos( radians( longitude ) - radians(2.3622728) ) 
+ sin( radians(48.8558966) )
* sin( radians( latitude ) )
) < 20);

I have tried something like this:

List<FamilyAdvertisement> foundFamilyAdvertisements = from(qFamilyAdvertisement).where(qFamilyAdvertisement.member.address.in(

                new JPASubQuery().from(QAddress.address).where(formula.lt(20)))

                ).list(qFamilyAdvertisement);

where formula is given above but I am not sure how to express a noncorrelated subquery in QueryDSL and especially the in operator above seems to be problematical...

edit4:

The following subquery now works:

List<FamilyAdvertisement> foundFamilyAdvertisements = 
        from(qFamilyAdvertisement).where(qFamilyAdvertisement.member.address.in(new JPASubQuery().from(QAddress.address).where(formula.lt(20)).list(QAddress.address))).list(qFamilyAdvertisement);

解决方案

This path is too long for eager initialization

qFamilyAdvertisement.member.address.latitude;

Please read here more about path initialization in Querydsl http://www.querydsl.com/static/querydsl/3.1.0/reference/html/ch03s04.html#d0e1699

这篇关于使用QueryDSL为了查询近距离点的数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆