简体   繁体   中英

How to replace table name with parameter value while using Spring Data JPA nativeQuery

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 "'".

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

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

You can use EntityManager in JPA project.

   @Autowired
   EntityManager entityManager;

   Query createQuery(String tableName) {
       return entityManager.createNativeQuery("select * from " + tableName);
   }

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.

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM