2010-11-10 7 views
1

J'ai actuellement les critères ci-dessous: -Critères Hibernate - voir

Criteria addr = criteria.createCriteria("location.address"); 
       addr.add((Restrictions.and(Restrictions.between("latitude", latmin,  
         latmax), Restrictions.between("longitude", truelongmin, truelongmax)))); 

       String sql = "SQRT(POW(69.1 * ({alias}.latitude - " + point[1]  
         +") , 2) + POW(69.1 * ("+point[0] +" - {alias}.longitude) * COS({alias}.latitude /" 
         +" 57.3) , 2)) < "+distance;  
       addr.add(Restrictions.sqlRestriction(sql)); 

Ce que je voudrais faire est idéalement pour pouvoir commander par la distance. L'être équivalent mySQL: -

SELECT * , (
SQRT(POW(69.1 * (latitude - 51.3814282) , 2) + POW(69.1 * (- 2.3574537 - longitude) * COS(latitude/57.3) , 2)) 
) AS distance 
FROM `address` 
WHERE (
SQRT(POW(69.1 * (latitude - 51.3814282) , 2) + POW(69.1 * (- 2.3574537 - longitude) * COS(latitude/57.3) , 2)) 
) < 10.0 
ORDER BY distance DESC 
LIMIT 0 , 30 

Quelle est la meilleure façon de le faire en veille prolongée? J'ai essayé createCriteria/createAlias ​​("distance", "fonction")

Idéalement, je voudrais faire cela après la restriction sur Latmin et Latmax car cela diminue le jeu de résultats et donc le nombre de calculs (aussi le sql fait le même calcul deux fois: S) cependant toute suggestion serait la plus appréciée.

Cheers, Rob

Répondre

2

Hibernate prend en charge les requêtes natives juste pour des situations comme celle-ci :)

EDIT **

Je ne l'ai pas testé, mais quelque chose comme ce qui suit devrait fonctionner:

StringBuilder sql = new StringBuilder(); 

sql.append("SELECT *"); 
sql.append(", (SQRT(POW(69.1 * (latitude - 51.3814282) , 2) + POW(69.1 * (- 2.3574537 - longitude) * COS(latitude/57.3) , 2))) AS distance"); 
sql.append(" FROM `address`"); 
sql.append(" WHERE (SQRT(POW(69.1 * (latitude - 51.3814282) , 2) + POW(69.1 * (- 2.3574537 - longitude) * COS(latitude/57.3) , 2))) < 10.0"); 
sql.append(" ORDER BY distance DESC"); 
sql.append(" LIMIT 0 , 30"); 

SQLQuery query = session.createSQLQuery(sql.toString()); 
// call query.addScalar(..) for other fields you select 
query.addScalar("distance", Hibernate.BIG_DECIMAL) 

//Where AddressBean is the object that maps to a row of this resultset 
query.setResultTransformer(Transformers.aliasToBean(AddressBean.class)); 

List<AddressBean> list = new ArrayList<AddressBean>(100); 
for (Object object : query.list()) { 
    list.add((AddressBean)object); 
}