java - 如何使用 Spring Data JPA 执行存储为字符串的查询?

标签 java sql spring spring-data-jpa

我正在以编程方式将 SQL 查询构造为字符串,并希望将其作为 SQL 语句执行,但我使用的是 Spring Data JPA,并且无法将 JDBC 与准备好的语句结合使用。这在 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)
}
}

最佳答案

您的查询看起来太动态,无法被 Spring Data JPA 注释理解。事实上,当您尝试将 SQL 注入(inject)参数字段时,您尝试的解决方法将无效,因此框架将阻止您这样做以防止 SQL 注入(inject)。

您可以将自定义行为添加到存储库并实现准备好的语句(请参阅如何从 EntityManager here 获取 session )。基本上:

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);并多次调用它。性能较差,但有时简单会带来返回。

关于java - 如何使用 Spring Data JPA 执行存储为字符串的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43524569/

相关文章:

mysql - 不使用函数在mysql中作为列行

java - 如果将常量返回给 hashcode 并将 false 返回给 equals 会发生什么

java - run() 方法未使用 start() 执行

sql - 触发插入旧值-已更新的值

java - 在 Spring/Hibernate 中加载社交图 - Hibernate session 持续时间

java - Spring security - 禁用注销重定向

java - Spring Webapplistener 问题

java - 打印对象数组会出现空指针异常

java - 如何设置字节中的特定位以进行 BLE 数据传输?

mysql - 在现有列的值中添加字符