-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
The example code can be found here: https://github.com/gamlerhart/adbcj/tree/master/adbcj-demo
First add the Maven dependency and repository. Currently only snapshots are provided: Repository:
<repository>
<id>gamlor-snapshot</id>
<url>https://raw.github.com/gamlerhart/gamlor-mvn/master/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<layout>default</layout>
</repository>
Dependency (for MySQL):
<dependency>
<groupId>org.adbcj</groupId>
<artifactId>adbcj-api</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.adbcj</groupId>
<artifactId>adbcj-connection-pool</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.adbcj</groupId>
<artifactId>mysql-async-driver</artifactId>
<version>0.6-SNAPSHOT</version>
</dependency>
Note that using native JAVA programming in an asynchronous fashion is not that easy. ADBCJ is a rather low level API. We recommend to use higher level APIs, like the one for Scala.
NOTE: During development you we recommend to add the JVM flag "-Dorg.adbcj.debug=true". See also here.
Anyways, let's connect with Java. We first create a connection manager, which holds all connections. Usually you have only one connection manager in the system for each database. Note the "pooled" keyword in the connection string. This will use the connection pool
// We assume we have a MySQL server running on localhost
// Database name: adbcj-demo
// User: adbcj
// Password: adbc-pwd
// A connection manager creates new connections for you.
// Usually you have one instance in your system.
// when you close the connection-manager, all associated connections are closed to.
final ConnectionManager connectionManager = ConnectionManagerProvider.createConnectionManager(
"adbcj:pooled:mysql://localhost/adbcj-demo",
"adbcj",
"adbc-pwd"
);
Connecting is asynchronous. So we add a handler to react when it's done and continue from there:
// Connect to your database. It's asynchronous.
// This means we react on it when done
final DbFuture<Connection> connect = connectionManager.connect();
connect.addListener(new DbListener<Connection>() {
@Override
public void onCompletion(DbFuture<Connection> connectionDbFuture) {
switch (connectionDbFuture.getState()){
case SUCCESS:
// On success we continue with our program
// To not block the main thread we always should react in listeners
final Connection connection = connectionDbFuture.getResult();
continueAndCreateSchema(connection);
break;
case FAILURE:
connectionDbFuture.getException().printStackTrace();
break;
case CANCELLED:
System.out.println("Cancelled");
break;
}
}
});
Running queries have the same pattern: Send the query and react when the result arrives:
private static void continueAndCreateSchema(final Connection connection) {
// Again, we send the query and add a listener to react to it
connection.executeUpdate("CREATE TABLE IF NOT EXISTS posts(\n" +
" id int NOT NULL AUTO_INCREMENT,\n" +
" title varchar(255) NOT NULL,\n" +
" content TEXT NOT NULL,\n" +
" PRIMARY KEY (id)\n" +
") ENGINE = INNODB;").addListener(new DbListener<Result>() {
@Override
public void onCompletion(DbFuture<Result> resultDbFuture) {
switch (resultDbFuture.getState()) {
case SUCCESS:
System.out.println("Created Schema, Inserting");
continueWithInserting(connection);
break;
case FAILURE:
resultDbFuture.getException().printStackTrace();
break;
case CANCELLED:
System.out.println("Cancelled");
break;
}
}
});
}
#Pipeline You can 'pipeline' queries and inserts. Send queries and updates directly to the database. They will be sent immediately, avoiding waiting on the database side. Then await for the results:
private static void continueWithInserting(final Connection connection) {
// We can directly send multiple queries
// And then wait until everyone is done.
final DbSessionFuture<Result> firstPost = connection.executeUpdate("INSERT INTO posts(title,content) VALUES('The Title','TheContent')");
final DbSessionFuture<Result> secondPost = connection.executeUpdate("INSERT INTO posts(title,content) VALUES('Second Title','More Content')");
final DbSessionFuture<Result> thirdPost = connection.executeUpdate("INSERT INTO posts(title,content) VALUES('Third Title','Even More Content')");
final DbListener<Result> allDone = new DbListener<Result>() {
@Override
public void onCompletion(DbFuture<Result> resultSetDbFuture) {
switch (resultSetDbFuture.getState()) {
case SUCCESS:
// Check if everyone is done
if(firstPost.isDone()&&secondPost.isDone()&&thirdPost.isDone()){
continueWithSelect(connection);
}
break;
case FAILURE:
resultSetDbFuture.getException().printStackTrace();
break;
case CANCELLED:
System.out.println("Cancelled");
break;
}
}
};
// Register the listener to all instances
firstPost.addListener(allDone);
secondPost.addListener(allDone);
thirdPost.addListener(allDone);
}
Queries work the same as updates. The result sets in the futures are immutable. So you can safely close the connection, once you have the result. Note that close also returns a future, in case you want to be noticed when the connection actually closed.
private static void continueWithSelect(final Connection connection) {
connection.executeQuery("SELECT * FROM posts").addListener(new DbListener<ResultSet>() {
@Override
public void onCompletion(DbFuture<ResultSet> resultSetDbFuture) {
switch (resultSetDbFuture.getState()) {
case SUCCESS:
listResultSet(resultSetDbFuture.getResult());
// result sets are immutable. You can close the connection
connection.close();
break;
case FAILURE:
resultSetDbFuture.getException().printStackTrace();
break;
case CANCELLED:
System.out.println("Cancelled");
break;
}
}
});
}
private static void listResultSet(ResultSet result) {
for (Row row : result) {
System.out.println("ID: "+row.get("ID").getLong()+" with title "+row.get("title").getString());
}
}