jpaspring-data-jpaspring-boot-jpa

How SpringBoot JPA run DDL sql with dynamic tableName?


Yestody,I got this question, how jpa run DDL sql with dynamic tableName? usually,I just used DQL and DML like 'select,insert,update,delete'. such as :

public interface UserRepository extends JpaRepository<User, Integer> {

    @Query(value = "select a.* from user a where a.username = ? and a.password = ?", nativeQuery = true)
    List<User> loginCheck(String username, String password);

}

but when I required run DDL sql below

String sql = "create table " + tableName + " as select * from user where login_flag = '1'";

I don't find a way to solve this with Jpa (or EntityManager). Finally I used JDBC to run the DDL sql,but I think it's ugly...

Connection conn = null;
PreparedStatement ps = null;
String sql=" create table " + tableName + " as select * from user where login_flag = '1' ";
try {
    Class.forName(drive);
    conn = DriverManager.getConnection(url, username, password);
    ps = conn.prepareStatement(sql);
    ps.executeUpdate();
    ps.close();
    conn.close();
} catch (Exception e) {
    e.printStackTrace();
}

So,can jpa run DDL sql(such as CREATE/DROP/ALTER) wiht dynamic tableName in an easy way?


Solution

  • Your question seems to consist of two parts

    The first part

    can jpa run DDL sql

    Sure, just use entityManager.createNativeQuery("CREATE TABLE ...").executeUpdate(). This is probably not the best idea (you should be using a database migration tool like Flyway or Liquibase for DB creation), but it will work.

    Note that you might run into some issues, e.g. different RDBMSes have different requirements regarding transactions around DDL statements, but they can be solved quite easily most of the time.

    You're probably wondering how to get hold of an EntityManager when using Spring Data. See here for an explanation on how to create custom repository fragments where you can inject virtually anything you need.

    The second part

    with dynamic tableName

    JPA only supports parameters in certain clauses within the query, and identifiers are not one of them. You'll need to use string concatenation, I'm afraid.

    Why dynamic table names, though? It's not like your entity definitions are going to change at runtime. Static DDL scripts are generally less error-prone.