比较所有模型对象

时间:2013-03-26 16:19:55

标签: java playframework playframework-2.0

我希望能够将模型对象的id传递给方法,然后将其与该模型类型的所有其他对象进行比较,以查看某些属性是否匹配。我知道您可以使用Models Finder进行更多传统查询,但我需要使用我编写的一些自定义方法来进行比较。有没有办法遍历所有现有的模型对象,将它们的属性与相关对象的属性进行比较,存储匹配是某种列表。 Finder是否有能力做到这一点?

我正在使用EBean。

更新

所以我的模型实际上比我之前使用的书籍例子稍微复杂一些。它是存储用户旅行信息的模型。该模型的四个属性如下所示:

    public Double sLat;
    public Double sLon;
    public Double eLat;
    public Double eLon;

这些双打表示旅程起点的纬度和经度以及终点的经度和经度。我正在使用前一篇文章中描述的Harvesine公式:How can I measure distance and create a bounding box based on two latitude+longitude points in Java?

所以在我的模型中,我将使用下面的方法计算两点之间的距离:

public static double distFrom(double lat1, double lng1, double lat2, double lng2) {

    double earthRadius = 3958.75;
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double sindLat = Math.sin(dLat / 2);
    double sindLng = Math.sin(dLng / 2);
    double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
            * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = earthRadius * c;

    return dist;
}

我已经使用一些硬编码的虚拟数据对此进行了测试,看看它是否按预期使用此方法:

public static void journeyCompare(double lat1, double lng1, double lat2, double lng2,
                                      double lat3, double lng3, double lat4, double lng4) {

        double startMatch = distFrom(lat1, lng1, lat3, lng3);
        if(startMatch<=5) {
            System.out.println("Starting points are within five miles of each other");
            double endMatch = distFrom(lat2, lng2, lat4, lng4);
            if(endMatch<=5) {
                System.out.println("Start and end points are within five miles of each other!!! JOURNEY MATCH");
            }
            else {
                System.out.println("End points are too far apart");
            }
            }
            else {
            System.out.println("Starting points are too far apart");
            }

    }

所以我的问题是我如何能够使用这些方法 - 一次旅行,四个双重代表其点,并将其与其他所有旅程进行比较。我不确定是否有办法使用EBean finder来解决这个问题。

进一步更新:

所以我觉得我差点就在那里我现在遇到一个播放错误:找不到类型为Double的QueryString绑定器。我的新匹配方法:

public static List<Journey> matcher(Double startLat, Double startLon, Double endLat, Double endLon) {

    //Create a list to store matched journeys
    List<Journey> matchList = new ArrayList<Journey>();

    //Create a list that stores all pre-existing journeys
    List<Journey> allJourneys = new ArrayList<Journey>();
    allJourneys = find.all();

    for(Journey journey : allJourneys) {
        double distanceBetweenStart = distFrom(startLat, startLon, journey.sLat, journey.sLon);

        //if the starting points are within 3 miles of each other
        if(distanceBetweenStart <= 3) {
            //check end points
            double distanceBetweenEnd = distFrom(endLat, endLon, journey.eLat, journey.eLon);
            if(distanceBetweenEnd <= 3) {
                matchList.add(journey);
            }
        }
    }
            return matchList;
}

1 个答案:

答案 0 :(得分:2)

假设您正在使用JPA和Hibernate等库来实现持久性,那么有几种方法可以解决这个问题。

public static List<Book> findMatch(Book id){
    List<Book> allBooks = JPA.em().createQuery("FROM Book").getResultList();
    List<Book> matchedBooks = new ArrayList<Book>(); 
    for(Book b : allBooks){
        if(isPossibleMatch(b, id)) //assuming you define a .isPossibleMatch() method
            matchedBooks.add(b);
    }
    return matchedBooks;
}

public static List<Book> findMatch(Book id){
    Query query = JPA.em().createQuery("SELECT b FROM Book b WHERE b.fieldOne = :fieldOne AND b.fieldTwo : fieldTwo");
    query.setParameter("fieldOne", id.fieldOne);
    query.setParameter("fieldTwo", id.fieldTwo);
    return query.getResultList();
}

编辑:为了完整性,请保留上述内容,但这里是对Ebean解决方案的编辑。

http://www.playframework.com/documentation/2.0.4/JavaEbean中的示例所示,您可以为Book类实现静态“查找”字段。

public static Finder<Long,Book> find = new Finder<Long,Book>(Long.class, Book.class);

从那里,它将非常类似地匹配上面的JPA代码,但是通过调用

来获取所有Book对象列表的方式会有所不同
Book.find.all()

但是,如果您希望能够在评论中进行操作,例如查找2.50美元到4.50美元之间的图书,您可以使用Finder编写查询,如下所示:

Book.find.where().between("price", 2.5, 4.5).findList();

where()方法应证明对您有用,可以在http://www.avaje.org/static/javadoc/pub/com/avaje/ebean/Query.html#where%28%29

找到