Schema modifications through JDBC require submitting raw DDL commands via Statement instances. Because the SQL grammar for ALTER TABLE does not permit bind variables for identifiers such as table or column names, the command text must be composed explicitly before execution.
A robust implementation acquires the connection through DriverManager, dispatches the DDL with executeUpdate(), and delegates resource cleanup to a try-with-resources block:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class SchemaMigration {
private static final String DB_ENDPOINT = "jdbc:mysql://127.0.0.1:3306/app_data";
private static final String DB_ACCOUNT = "admin";
private static final String DB_SECRET = "changeme";
public static void introduceColumn(String table, String column, String definition) {
String ddl = String.format(
"ALTER TABLE %s ADD COLUMN %s %s",
table, column, definition
);
try (Connection dbLink = DriverManager.getConnection(DB_ENDPOINT, DB_ACCOUNT, DB_SECRET);
Statement ddlExecutor = dbLink.createStatement()) {
ddlExecutor.executeUpdate(ddl);
} catch (SQLException ex) {
throw new RuntimeException("Schema alteration failed: " + ddl, ex);
}
}
}
Important behavioral considerations:
- Resource ordering: The try-with-resources clause closes the
Statementbefore theConnection, preventing connection pool leaks and premature socket termination. - Return semantics:
executeUpdatereturns zero for successful DDL execution because no rows are affected by structural changes. - Transaction boundaries: Most MySQL and PostgreSQL drivers implicitly commit active transactions when they encounter DDL. Do not interleave schema changes and business-logic DML inside the same manual commit scope.
For consecutive dependent changes, reuse the same Statement across multiple executeUpdate calls while keeping the connection open:
try (Connection dbLink = DriverManager.getConnection(DB_ENDPOINT, DB_ACCOUNT, DB_SECRET);
Statement ddlExecutor = dbLink.createStatement()) {
ddlExecutor.executeUpdate("ALTER TABLE employees ADD COLUMN middle_name VARCHAR(50)");
ddlExecutor.executeUpdate("ALTER TABLE employees ADD INDEX idx_middle_name (middle_name)");
} catch (SQLException ex) {
throw new RuntimeException("Multi-step migration aborted", ex);
}
Drivers automatically release statement handles and TCP connections when control exits the try-with-reosurces scope.