2017-04-20 103 views
1

我編程構建我的SQL查詢string和希望執行它作爲一個SQL語句,但我使用Spring數據JPA,我不能夠使用JDBC預處理語句。這在JPA中可能嗎?如何使用Spring Data JPA執行存儲爲字符串的查詢?

public class Polygon { 

public static void main(String[] args) { 

    // Build Lat/Longs 

    Set<String[]> coordinates = new HashSet<>(); 

    coordinates.add(new String[]{"42", "-72.95333862304689"}); 
    coordinates.add(new String[]{"42.05337156043361", "-71.06643676757814"}); 
    coordinates.add(new String[]{"41.32732632036624", "-71.06643676757814"}); 
    coordinates.add(new String[]{"41.32732632036624", "-72.95333862304689"}); 
    coordinates.add(new String[]{"42.05337156043361", "-72"}); 

    // Trim & Build Query 

    String query = "SELECT * FROM SITE WHERE (LATITUDE LIKE "; 

    for(String[] c : coordinates){ 

     c[0] += ".0"; 
     c[1] += ".0"; 

     String[] latArray = c[0].split("\\."); 
     String[] lngArray = c[1].split("\\."); 

     String lat = latArray[0] + "." + latArray[1].substring(0, 1) + "%"; 
     String lng = lngArray[0] + "." + lngArray[1].substring(0, 1) + "%"; 

     query += lat + " AND LONGITUDE LIKE " + lng + ") OR (LATITUDE LIKE "; 
    } 

    query = query.substring(0, query.length() - 20) + ");"; 
    System.err.println(query); 

    /* 
    * This is the Query I am printing, which is correct 
    * 
    * SELECT * FROM SITE 
    * WHERE (LATITUDE LIKE 41.3% AND LONGITUDE LIKE -71.0%) 
    * OR (LATITUDE LIKE 42.0% AND LONGITUDE LIKE -72.0%) 
    * OR (LATITUDE LIKE 42.0% AND LONGITUDE LIKE -72.9%) 
    * OR (LATITUDE LIKE 42.0% AND LONGITUDE LIKE -71.0%) 
    * OR (LATITUDE LIKE 41.3% AND LONGITUDE LIKE -72.9%); 
    *  
    * How to execute this with Spring Data JPA? 
    */ 

    // @Query("SELECT * FROM SITE :where", nativeQuery = true) 
    // public List<SiteDTO> executeSiteQuery(@Param("where") String where); 
    // Doesn't Work, because (Syntax error on token ""SELECT * FROM SITE :where"", invalid MemberValuePairs) 
} 
} 

回答

1

您的查詢看起來過於動態,無法被Spring Data JPA註解理解。事實上,正如你想SQL注入到帕拉姆領域你試圖解決方法將不再有效,因此該框架將阻止你這樣做,以防止SQL注入。

您可以添加自定義行爲信息庫,並實現準備好的發言(見如何從EntityManager的here搶會話)。基本上是:

public class MyRepositoryImpl<SiteDTO, ID extends Serializable> 
    extends SimpleJpaRepository<SiteDTO, ID> implements MyRepository<SiteDTO, ID> { 

    private EntityManager entityManager; 

    // There are two constructors to choose from, either can be used. 
    public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager) { 
    super(domainClass, entityManager); 

    // This is the recommended method for accessing inherited class dependencies. 
    this.entityManager = entityManager; 
    } 

    public List<SiteDTO> executeSiteQuery(List<String> longitudesToMatch, List<String> latitudesToMatch) { 
    // Here you can grab the session from the entity manager and create your own query 
    } 
} 

否則,如果你認爲這是一個矯枉過正,你可能會考慮做您的查詢的or部分在Spring服務。我的意思是,像這樣public List<SiteDTO> executeSiteQuery(@Param("latitude") String latitude, @Param("longitude") String longitude);查詢並多次調用它。性能較差,但有時候簡單性付費。

+0

我能拿到的EntityManager而使用Spring的引導,因爲我們沒有這個配置在所有。它全部由Spring抽象和處理。 – jDub9

+0

@ jDub9這是春天啓動的最好的部分,你可以得到元素創建和框架的自動配置,然後用它們在你的自定義類,如果你想。 –

相關問題