H2 Database Engine - A very fast, open source, JDBC API database with embedded and server modes, transaction support, multi-version concurrency, browser-based console application, encrypted databases, fulltext search, and pure Java implementation with small footprint
—
H2 provides comprehensive JDBC 4.2 compliant database connectivity with embedded and server deployment modes. It supports standard JDBC APIs along with H2-specific enhancements for connection pooling, XA transactions, and various authentication methods.
The main H2 JDBC driver implementation.
public class Driver implements java.sql.Driver, JdbcDriverBackwardsCompat {
public Connection connect(String url, Properties info) throws SQLException;
public boolean acceptsURL(String url) throws SQLException;
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException;
public int getMajorVersion();
public int getMinorVersion();
public boolean jdbcCompliant();
// H2-specific methods
public static Driver load();
public static void unload();
public static void setDefaultConnection(Connection c);
}Usage Examples:
// Automatic driver loading (Java 6+)
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test", "sa", "");
// Manual driver registration (older Java versions)
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test", "sa", "");
// Using Properties
Properties props = new Properties();
props.setProperty("user", "sa");
props.setProperty("password", "mypassword");
props.setProperty("CACHE_SIZE", "32768");
Connection conn = DriverManager.getConnection("jdbc:h2:~/mydb", props);DataSource implementation supporting connection pooling and JEE integration.
public class JdbcDataSource implements DataSource, XADataSource,
ConnectionPoolDataSource,
Serializable, Referenceable {
// DataSource methods
public Connection getConnection() throws SQLException;
public Connection getConnection(String username, String password) throws SQLException;
// Configuration methods
public void setURL(String url);
public String getURL();
public void setUser(String user);
public String getUser();
public void setPassword(String password);
public void setDescription(String description);
public String getDescription();
// Connection pool methods
public PooledConnection getPooledConnection() throws SQLException;
public PooledConnection getPooledConnection(String user, String password) throws SQLException;
// XA methods
public XAConnection getXAConnection() throws SQLException;
public XAConnection getXAConnection(String user, String password) throws SQLException;
// Logging
public void setLogWriter(PrintWriter out);
public PrintWriter getLogWriter();
public void setLoginTimeout(int seconds);
public int getLoginTimeout();
}Usage Examples:
// Basic DataSource usage
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:~/mydb");
ds.setUser("sa");
ds.setPassword("mypassword");
ds.setDescription("My H2 Database");
Connection conn = ds.getConnection();
// In application server context (web.xml or context.xml)
// <Resource name="jdbc/h2db" auth="Container" type="javax.sql.DataSource"
// factory="org.h2.jdbcx.JdbcDataSourceFactory"
// url="jdbc:h2:~/mydb" user="sa" password=""/>
// JNDI lookup
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/h2db");
Connection conn = ds.getConnection();Simple connection pool implementation.
public class JdbcConnectionPool implements DataSource {
public static JdbcConnectionPool create(String url, String user, String password);
public static JdbcConnectionPool create(DataSource dataSource);
public Connection getConnection() throws SQLException;
public Connection getConnection(String username, String password) throws SQLException;
// Pool management
public void setMaxConnections(int max);
public int getMaxConnections();
public void setTimeoutMs(int timeoutMs);
public int getTimeoutMs();
// Pool monitoring
public int getActiveConnections();
public void dispose();
}Usage Examples:
// Create connection pool
JdbcConnectionPool cp = JdbcConnectionPool.create(
"jdbc:h2:~/mydb", "sa", "mypassword");
cp.setMaxConnections(10);
cp.setTimeoutMs(30000);
// Use pooled connections
Connection conn = cp.getConnection();
try {
// database operations
} finally {
conn.close(); // returns connection to pool
}
// Clean up pool
cp.dispose();XA (distributed transaction) support.
public class JdbcXAConnection implements XAConnection {
public XAResource getXAResource() throws SQLException;
public Connection getConnection() throws SQLException;
public void close() throws SQLException;
// Event listeners
public void addConnectionEventListener(ConnectionEventListener listener);
public void removeConnectionEventListener(ConnectionEventListener listener);
}Usage Examples:
// XA transaction usage (typically managed by application server)
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:~/mydb");
XAConnection xaConn = ds.getXAConnection("sa", "");
XAResource xaRes = xaConn.getXAResource();
Connection conn = xaConn.getConnection();
// XA transaction management
Xid xid = new MyXid();
xaRes.start(xid, XAResource.TMNOFLAGS);
// perform database operations
xaRes.end(xid, XAResource.TMSUCCESS);
xaRes.prepare(xid);
xaRes.commit(xid, false);H2 supports various connection URL formats for different deployment scenarios:
// In-memory database (data lost when JVM exits)
"jdbc:h2:mem:dbname"
"jdbc:h2:mem:dbname;DB_CLOSE_DELAY=-1" // keep open until explicitly closed
// File-based database
"jdbc:h2:~/dbname" // user home directory
"jdbc:h2:./dbname" // current directory
"jdbc:h2:/path/to/dbname" // absolute path
"jdbc:h2:C:/data/dbname" // Windows path
// Split database files
"jdbc:h2:split:~/dbname" // split into multiple files// TCP server connection
"jdbc:h2:tcp://localhost/~/dbname"
"jdbc:h2:tcp://server:9092/~/dbname"
// SSL encrypted connection
"jdbc:h2:ssl://localhost/~/dbname"
// Mixed mode (embedded + server)
"jdbc:h2:~/dbname;AUTO_SERVER=TRUE"
"jdbc:h2:~/dbname;AUTO_SERVER=TRUE;AUTO_SERVER_PORT=9090"Common connection parameters can be appended to URLs:
// Authentication
"jdbc:h2:~/db;USER=sa;PASSWORD=mypass"
// Encryption
"jdbc:h2:~/secure;CIPHER=AES" // AES encryption
"jdbc:h2:~/secure;CIPHER=XTEA" // XTEA encryption
// Access control
"jdbc:h2:~/db;ACCESS_MODE_DATA=r" // read-only
"jdbc:h2:~/db;ACCESS_MODE_LOG=r" // read-only transaction log
// Performance tuning
"jdbc:h2:~/db;CACHE_SIZE=65536" // cache size in KB
"jdbc:h2:~/db;LOCK_TIMEOUT=10000" // lock timeout in ms
"jdbc:h2:~/db;WRITE_DELAY=0" // write delay in ms
// Compatibility
"jdbc:h2:~/db;MODE=MySQL" // MySQL compatibility
"jdbc:h2:~/db;MODE=PostgreSQL" // PostgreSQL compatibility
"jdbc:h2:~/db;MODE=Oracle" // Oracle compatibility
// Debugging
"jdbc:h2:~/db;TRACE_LEVEL_FILE=2" // file trace level
"jdbc:h2:~/db;TRACE_LEVEL_SYSTEM_OUT=2" // console trace levelProperties can be set via connection URLs or Properties object:
// Common properties
public static final String USER = "user";
public static final String PASSWORD = "password";
public static final String CACHE_SIZE = "CACHE_SIZE";
public static final String LOCK_TIMEOUT = "LOCK_TIMEOUT";
public static final String WRITE_DELAY = "WRITE_DELAY";
public static final String TRACE_LEVEL_FILE = "TRACE_LEVEL_FILE";
public static final String MODE = "MODE";
public static final String CIPHER = "CIPHER";
public static final String ACCESS_MODE_DATA = "ACCESS_MODE_DATA";
public static final String AUTO_SERVER = "AUTO_SERVER";Usage Examples:
Properties props = new Properties();
props.setProperty("user", "sa");
props.setProperty("password", "");
props.setProperty("CACHE_SIZE", "32768");
props.setProperty("TRACE_LEVEL_FILE", "2");
props.setProperty("MODE", "PostgreSQL");
Connection conn = DriverManager.getConnection("jdbc:h2:~/mydb", props);public class DatabaseManager {
private static JdbcConnectionPool pool;
static {
pool = JdbcConnectionPool.create(
"jdbc:h2:~/production", "sa", "strongpassword");
pool.setMaxConnections(20);
pool.setTimeoutMs(30000);
}
public static Connection getConnection() throws SQLException {
return pool.getConnection();
}
public static void shutdown() {
if (pool != null) {
pool.dispose();
}
}
// Usage pattern
public void performDatabaseOperation() {
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?")) {
stmt.setInt(1, 123);
ResultSet rs = stmt.executeQuery();
// process results
} catch (SQLException e) {
// handle exception
e.printStackTrace();
}
}
}// Custom authentication
"jdbc:h2:~/db;AUTHENTICATOR=com.mycompany.MyAuthenticator"
// User to roles mapping
"jdbc:h2:~/db;USER_TO_ROLES_MAPPER=com.mycompany.MyMapper"
// Credential validation
"jdbc:h2:~/db;CREDENTIALS_VALIDATOR=com.mycompany.MyValidator"
// Example custom authenticator
public class MyAuthenticator implements Authenticator {
@Override
public boolean authenticate(String userName, String password, String realm) {
// Custom authentication logic
return validateUser(userName, password);
}
}H2 JDBC operations throw standard SQLException with H2-specific error codes:
try {
Connection conn = DriverManager.getConnection("jdbc:h2:~/db", "sa", "");
// database operations
} catch (SQLException e) {
int errorCode = e.getErrorCode();
String sqlState = e.getSQLState();
// H2-specific error handling
switch (errorCode) {
case ErrorCode.DATABASE_NOT_FOUND_1:
System.err.println("Database file not found");
break;
case ErrorCode.WRONG_USER_OR_PASSWORD:
System.err.println("Authentication failed");
break;
case ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1:
System.err.println("Table not found: " + e.getMessage());
break;
default:
System.err.println("Database error: " + e.getMessage());
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-h2database--h2