2

like this:

public interface XXXRepository extends CrudRepository<XXX, Integer> {
@Query(value = "select * from ?1 where ...", nativeQuery = true)
List<XXX> findByXXX(String tableName, ...);}

It gives MYSQL syntax error with upon codes. The syntax error shows that the table name in the SQL is surrounded with "'".

TanvirChowdhury
  • 2,498
  • 23
  • 28
Jason
  • 303
  • 1
  • 5
  • 13

5 Answers5

17

This is not possible. Parameters are only allowed in the where clause.

Simon Martinelli
  • 34,053
  • 5
  • 48
  • 82
3

If you are using a Spring Data repository, you can use #{#entityName} SpEL expression as a placeholder for the entity name. Depending on your use case, it is not necessary to use the entity name as method parameter anymore.

I am not sure if this feature works when you use nativeQuery = true

See the documentation here: https://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/#jpa.query.spel-expressions

Stefan
  • 69
  • 2
  • It does not work in native query only work with HQL. – Delirante Aug 28 '20 at 08:00
  • SpEl expressions works for me in native query: @Query(value = "select '#{#tableName}'", nativeQuery = true) String selectEntityName(); But I didn't find way to insert real table name. – jurek Oct 19 '22 at 06:54
1

You can use EntityManager in JPA project.

   @Autowired
   EntityManager entityManager;

   Query createQuery(String tableName) {
       return entityManager.createNativeQuery("select * from " + tableName);
   }
aboger
  • 2,214
  • 6
  • 33
  • 47
zy_sun
  • 175
  • 1
  • 11
0

I have a workaround.
It uses javax.persistence.EntityManager and String.format to do that.

package com.example.test.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import javax.persistence.EntityManager;

@Component
public class SomeDao {
    @Autowired
    EntityManager em;

    public List<?> listFoodMoneyDateOfPayment(int departmentId, String sumKey, String tableName) {
        String s = "SELECT SUM(%s) AS money, CONCAT(YEAR(apply_time), '-', MONTH(apply_time)) AS yearmonth " +
                "FROM (%s) WHERE department_id = %d GROUP BY yearmonth";
        String sql = String.format(s, sumKey, tableName, departmentId);
        System.out.println(sql);

        List<?> test = em.createNativeQuery(sql).getResultList();

        return test;
    }
}

The invoke code is that:

@RestController
@RequestMapping("/api")
public class TestController {

    @Autowired
    private SomeDao dao;

    @RequestMapping("/test2")
    public HttpEntity test2() {
        var l = dao.listFoodMoneyDateOfPayment(12, "food_payment", "payment_application");
        System.out.println(l.getClass());
        System.out.println(JSON.toJSONString(l));
        return ResultBean.success();
    }
}

And it works well.
But you should check the arguments passed in.

h10g
  • 396
  • 1
  • 4
  • 12
-1

This is possible with jdbc:

@Autowired
JdbcTemplate jdbcTemplate;

public String nativeQueryToString(String query) {

    try {

        return jdbcTemplate.queryForObject(query, String.class);
        
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}