META-INF/services/java.sql.Driver
file// You need to have h2.jar in the same folder
// Compile and run: javac App.java; java -cp ".:h2.jar" App
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test");
Statement s = conn.createStatement();
s.execute("CREATE TABLE person(id int, name varchar, lastname varchar);");
s.execute("INSERT INTO person VALUES(1, 'Koray', 'Tugay');");
s.execute("INSERT INTO person VALUES(2, 'John', 'Doe');");
s.execute("INSERT INTO person VALUES(3, 'Jane', 'Doe');");
s.execute("INSERT INTO person VALUES(4, 'Pinar', 'Tugay');");
ResultSet rs = s.executeQuery("SELECT * FROM person");
ResultSetMetaData rsmd = rs.getMetaData();
int colCount = rsmd.getColumnCount();
String[] columnNames = new String[colCount];
for (int i = 1; i <= colCount; i++)
columnNames[i-1] = rsmd.getColumnName(i);
String header = Stream.of(columnNames).collect(Collectors.joining("\t"));
System.out.println(header);
while (rs.next()) {
for (String columnName : columnNames)
System.out.print(rs.getObject(columnName) + "\t");
System.out.println("");
}
ID NAME LASTNAME
1 Koray Tugay
2 John Doe
3 Jane Doe
4 Pinar Tugay
Connection
, call DriverManager.getConnection(String jdbcUrl)
Statement
, call Connection.createStatement()
ResultSet
, call Statement.executeQuery(String query)
executeQuery
returns a ResultSet
object that you can extract further information fromResultSet
, call Statement.executeUpdate(String query)
executeUpdate
returns number of rows affectedResultSet
or number of affected rows, call Statement.execute(String query)
executeQuery
returns a boolean value: true
if a ResultSet is returned, false
if number of affected rows is returnedgetResultSet
or getUpdateCount
can then be called based on the the returning boolean valueTYPE_FORWARD_ONLY
TYPE_SCROLL_INSENSITIVE
TYPE_SCROLL_SENSITIVE
CONCUR_READ_ONLY
CONCUR_UPDATABLE
Connection con = DriverManager.getConnection("jdbc:derby:mydb;create=true");
Statement st = con.createStatement();
try {
st.execute("DROP TABLE person");
} catch (Exception ignored) {}
st.execute("CREATE TABLE person(Id INT, Name VARCHAR(255))");
st.execute("INSERT INTO person VALUES(1, 'Koray')");
st.execute("INSERT INTO person VALUES(2, 'Deniz')");
st.execute("INSERT INTO person VALUES(3, 'Toprak')");
st.execute("INSERT INTO person VALUES(4, 'Pinar')");
st.close();
// ResultSet.TYPE_SCROLL_INSENSITIVE lets you move cursor around
// contrary to FORWARD_ONLY
// ResultSet.CONCUR_READ_ONLY is the default where we can only read data
// and not update it
st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = st.executeQuery("SELECT * FROM person");
rs.last(); // Move to last row
int count = rs.getRow(); // Get row number, in this example 4
rs.beforeFirst(); // Position cursor back
st.close();
con.close();
derby.jar
in the folderkillall -9 java; clear; javac App.java; java -cp ".:derby.jar" App;
killall -9 java; clear; javac App.java; java -cp ".:derby.jar" App true;
import java.sql.*;
import java.util.*;
class App {
static Map<Integer, String> isolationLevels = new HashMap<>();
static {
isolationLevels.put(Connection.TRANSACTION_READ_COMMITTED,
"Connection.TRANSACTION_READ_COMMITTED");
isolationLevels.put(Connection.TRANSACTION_READ_UNCOMMITTED,
"Connection.TRANSACTION_READ_UNCOMMITTED");
}
public static void main(String[] args) throws SQLException {
String url = "jdbc:derby:coffeshop;create=true";
Connection con = DriverManager.getConnection(url);
// Default for Derby is Connection.TRANSACTION_READ_COMMITTED
println("Def: " + isolationLevels.get(con.getTransactionIsolation()));
Statement st = con.createStatement();
try {
st.execute("DROP TABLE coffee");
} catch (Exception ignored) {}
st.execute("CREATE TABLE coffee(Type VARCHAR(255), Price INT)");
st.executeUpdate("INSERT INTO coffee VALUES ('Blonde', 1)");
st.close();
con.close();
// Example starts here
Connection supplier = DriverManager.getConnection(url);
Connection consumer = DriverManager.getConnection(url);
supplier.setAutoCommit(false);
supplier.createStatement().executeUpdate("UPDATE coffee SET Price = 2");
if (args.length > 0 && args[0].equals("true")) {
// Allow consumer to read uncommitted data
consumer
.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
}
// Application blocks here
// if consumers transaction isolation is TRANSACTION_READ_COMMITTED
ResultSet rs
= consumer.createStatement().executeQuery("SELECT Price FROM coffee");
rs.next();
// Prints 10
// if consumers transaction isolation is TRANSACTION_READ_UNCOMMITTED
// This is potentially dirty data since supplier may choose to rollback
System.out.println(rs.getInt("Price"));
supplier.rollback();
supplier.close();
consumer.close();
}
}
TRANSACTION_READ_COMMITTED
supplier
is not in auto commit mode, and is not committing its changesconsumer
(and the whole application) to block since it is only allowed to read committed datatrue
argument when calling the program, consumer
s isolation level will be TRANSACTION_READ_UNCOMMITTED
consumer
to read uncommitted, potentially dirty data