Skip to content

Commit 4f6858a

Browse files
author
Thomas Varsamidis
committed
Demo for JDBC connections and for Hikari connection pooling
1 parent 278e2af commit 4f6858a

File tree

4 files changed

+641
-10
lines changed

4 files changed

+641
-10
lines changed

java-path-core-databases/pom.xml

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,38 @@
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<!-- Packaging -->
6+
<modelVersion>4.0.0</modelVersion>
7+
<packaging>jar</packaging>
8+
9+
<!-- Versioning -->
10+
<artifactId>java-path-core-database</artifactId>
511
<parent>
6-
<artifactId>java-path-core</artifactId>
712
<groupId>gr.codelearn</groupId>
13+
<artifactId>java-path-core</artifactId>
814
<version>2021.1.0</version>
915
</parent>
10-
<modelVersion>4.0.0</modelVersion>
11-
12-
<artifactId>java-path-core-databases</artifactId>
1316

14-
<properties>
15-
<maven.compiler.source>17</maven.compiler.source>
16-
<maven.compiler.target>17</maven.compiler.target>
17-
</properties>
17+
<!-- Meta-data -->
18+
<name>[${project.artifactId}]</name>
19+
<description>Java Learning @ Development Path, Core module, Database connectivity demonstration</description>
1820

21+
<!-- Dependencies -->
1922
<dependencies>
20-
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
2123
<dependency>
2224
<groupId>com.h2database</groupId>
2325
<artifactId>h2</artifactId>
2426
<version>1.4.200</version>
2527
</dependency>
28+
<dependency>
29+
<groupId>com.zaxxer</groupId>
30+
<artifactId>HikariCP</artifactId>
31+
<version>4.0.3</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>com.thedeanda</groupId>
35+
<artifactId>lorem</artifactId>
36+
<version>2.1</version>
37+
</dependency>
2638
</dependencies>
27-
2839
</project>
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
package gr.codelearn.core.showcase.databases;
2+
3+
import com.thedeanda.lorem.Lorem;
4+
import com.thedeanda.lorem.LoremIpsum;
5+
import org.h2.tools.Server;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
import java.io.IOException;
10+
import java.io.InputStream;
11+
import java.sql.Connection;
12+
import java.sql.DriverManager;
13+
import java.sql.PreparedStatement;
14+
import java.sql.ResultSet;
15+
import java.sql.SQLException;
16+
import java.sql.Statement;
17+
import java.util.Arrays;
18+
import java.util.Properties;
19+
import java.util.concurrent.ThreadLocalRandom;
20+
21+
import static java.lang.System.exit;
22+
import static org.h2.tools.Server.startWebServer;
23+
24+
public class DatabaseClassicConnection {
25+
private static final Logger logger = LoggerFactory.getLogger(DatabaseClassicConnection.class);
26+
private static final Lorem generator = LoremIpsum.getInstance();
27+
28+
private static final String DB_CONNECTION_URL_FILE_MODE = "jdbc:h2:~/sample";
29+
private static final String DB_CONNECTION_URL_MEMORY_MODE = "jdbc:h2:mem:sample";
30+
private static final String DB_USERNAME = "sa";
31+
private static final String DB_PASSWORD = "";
32+
33+
private final Properties sqlCommands = new Properties();
34+
private Server server;
35+
36+
public static void main(String[] args) {
37+
if (args.length == 0) {
38+
logger.debug("No arguments passed.");
39+
}
40+
41+
DatabaseClassicConnection demo = new DatabaseClassicConnection();
42+
demo.loadSqlCommands();
43+
demo.startH2Server();
44+
demo.loadDatabaseDriver();
45+
46+
// We need to share the connection otherwise we want be able to see memory databases. Following a different
47+
// scenario, we will need to utilize file mode(store db files in a specific file location.
48+
Connection connection = demo.getConnection();
49+
50+
demo.createTable(connection);
51+
demo.insertData(connection);
52+
53+
// Commit transaction
54+
demo.commitData(connection);
55+
56+
demo.insertGeneratedData(connection, 20);
57+
demo.readData(connection);
58+
59+
demo.commitData(connection);
60+
demo.rollbackData(connection);
61+
demo.readData(connection);
62+
demo.insertGeneratedData(connection, 30);
63+
demo.readData(connection);
64+
demo.updateData(connection);
65+
demo.readData(connection);
66+
demo.deleteData(connection);
67+
demo.readData(connection);
68+
69+
demo.stopH2Server();
70+
}
71+
72+
private void insertGeneratedData(Connection connection, int numberOfInserts) {
73+
74+
//INSERT INTO Registration VALUES (?, ?, ?, ?);
75+
//INSERT INTO Registration VALUES (101, 'John', 'Smith', 18);
76+
77+
try (PreparedStatement preparedStatement = connection.prepareStatement(
78+
sqlCommands.getProperty("insert.table.000"))) {
79+
80+
int maximumIdValue = findMaximumIdValue(connection);
81+
batchInsert(preparedStatement, numberOfInserts, maximumIdValue);
82+
83+
int[] rowsAffectedArray = preparedStatement.executeBatch();
84+
logger.info("Insert batch command were successful with {} row(s) affected.", Arrays.stream(
85+
rowsAffectedArray).summaryStatistics().getSum());
86+
87+
} catch (SQLException ex) {
88+
logger.error("Error while inserting data.", ex);
89+
90+
}
91+
}
92+
93+
private int findMaximumIdValue(Connection connection) {
94+
try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(
95+
sqlCommands.getProperty("select.table.002"))) {
96+
97+
// isBeforeFirst returns false if the cursor is not before the first record or if there are no rows in the
98+
// ResultSet.
99+
if (resultSet.isBeforeFirst()) {
100+
resultSet.next();
101+
102+
logger.info("---------------------------------------------------------------------");
103+
logger.info("Maximum id value found is {}.", resultSet.getInt(1));
104+
logger.info("---------------------------------------------------------------------");
105+
106+
return resultSet.getInt(1);
107+
}
108+
109+
} catch (SQLException ex) {
110+
logger.error("Error while reading data.", ex);
111+
}
112+
113+
return 0;
114+
115+
}
116+
117+
private void batchInsert(PreparedStatement preparedStatement, int numberOfInserts, int maximumIdValue) {
118+
for (int i = 1; i <= numberOfInserts; i++) {
119+
try {
120+
preparedStatement.clearParameters();
121+
preparedStatement.setInt(1, maximumIdValue + i);
122+
preparedStatement.setString(2, generator.getFirstName());
123+
preparedStatement.setString(3, generator.getLastName());
124+
preparedStatement.setInt(4, ThreadLocalRandom.current().nextInt(18, 75));
125+
preparedStatement.addBatch();
126+
} catch (SQLException e) {
127+
e.printStackTrace();
128+
}
129+
}
130+
}
131+
132+
private void rollbackData(Connection connection) {
133+
try {
134+
connection.rollback();
135+
logger.info("Uncommitted data was rolled back from the database");
136+
} catch (SQLException e) {
137+
e.printStackTrace();
138+
}
139+
140+
}
141+
142+
private void readData(Connection connection) {
143+
try (Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
144+
ResultSet.CONCUR_READ_ONLY);
145+
ResultSet resultSet = statement.executeQuery(sqlCommands.getProperty("select.table.001"))) {
146+
147+
logger.info("---------------------------------------------------------------------");
148+
int rowCount = 1;
149+
while (resultSet.next()) {
150+
logger.info("{}. {}:{}, {}:{}, {}:{}, {}:{}", rowCount++, resultSet.getMetaData().getColumnName(1),
151+
resultSet.getString(1), resultSet.getMetaData().getColumnName(2), resultSet.getString(2),
152+
resultSet.getMetaData().getColumnName(3), resultSet.getString(3),
153+
resultSet.getMetaData().getColumnName(4), resultSet.getString(4));
154+
}
155+
logger.info("---------------------------------------------------------------------");
156+
157+
} catch (SQLException ex) {
158+
logger.error("Error while reading data.", ex);
159+
}
160+
}
161+
162+
private void commitData(Connection connection) {
163+
try {
164+
connection.commit();
165+
logger.info("Data was commited in the database");
166+
} catch (SQLException e) {
167+
e.printStackTrace();
168+
}
169+
}
170+
171+
private void insertData(Connection connection) {
172+
try (Statement statement = connection.createStatement()) {
173+
runInsertCommands(statement, sqlCommands.getProperty("insert.table.001"),
174+
sqlCommands.getProperty("insert.table.002"), sqlCommands.getProperty("insert.table.003"),
175+
sqlCommands.getProperty("insert.table.004"));
176+
177+
connection.setAutoCommit(false);
178+
statement.addBatch(sqlCommands.getProperty("insert.table.005"));
179+
statement.addBatch(sqlCommands.getProperty("insert.table.006"));
180+
statement.addBatch(sqlCommands.getProperty("insert.table.007"));
181+
statement.addBatch(sqlCommands.getProperty("insert.table.008"));
182+
statement.addBatch(sqlCommands.getProperty("insert.table.009"));
183+
statement.addBatch(sqlCommands.getProperty("insert.table.010"));
184+
int[] rowsAffectedArray = statement.executeBatch();
185+
logger.info("Insert command was successful with {} rows updated", Arrays.stream(rowsAffectedArray)
186+
.summaryStatistics().getSum());
187+
} catch (SQLException e) {
188+
e.printStackTrace();
189+
}
190+
}
191+
192+
private void updateData(final Connection connection) {
193+
try (Statement statement = connection.createStatement()) {
194+
logger.info("Update command was successful with {} row(s) affected",
195+
statement.executeUpdate(sqlCommands.getProperty("update.table.001")));
196+
} catch (SQLException ex) {
197+
logger.error("Error while updating data.", ex);
198+
}
199+
}
200+
201+
private void deleteData(final Connection connection) {
202+
try (Statement statement = connection.createStatement()) {
203+
logger.info("Delete command was successful with {} row(s) affected",
204+
statement.executeUpdate(sqlCommands.getProperty("delete.table.001")));
205+
} catch (SQLException ex) {
206+
logger.error("Error while deleting data.", ex);
207+
}
208+
}
209+
210+
private void runInsertCommands(Statement statement, String... commands) {
211+
for (String command : commands) {
212+
try {
213+
statement.executeUpdate(command);
214+
logger.info("Execute update successful: {}", command);
215+
} catch (SQLException e) {
216+
e.printStackTrace();
217+
}
218+
}
219+
}
220+
221+
private void createTable(Connection connection) {
222+
// createStatement by default:
223+
// TYPE_FORWARD_ONLY: you can only move forward on the result set, not backward, so you get an exception when
224+
// you try to go back
225+
// CONCUR_READ_ONLY: This type of result set is not updatable. i.e. once you get a ResultSet object you cannot update its contents.
226+
try (Statement statement = connection.createStatement()) {
227+
String sqlText = sqlCommands.getProperty("create.table");
228+
int result = statement.executeUpdate(sqlText);
229+
logger.info("Created table command was successful with result {}.", result);
230+
} catch (SQLException ex) {
231+
logger.error("Error while creating table(s).", ex);
232+
exit(-1);
233+
}
234+
}
235+
236+
private void loadSqlCommands() {
237+
try (InputStream is = DatabaseClassicConnection.class.getClassLoader().getResourceAsStream("sql.properties")) {
238+
if (is != null) {
239+
sqlCommands.load(is);
240+
logger.info("SQL commands were loaded");
241+
} else {
242+
logger.info("SQL commands were not loaded");
243+
}
244+
} catch (IOException e) {
245+
e.printStackTrace();
246+
}
247+
}
248+
249+
private Connection getConnection() {
250+
Connection connection = null;
251+
try {
252+
connection = DriverManager.getConnection(DB_CONNECTION_URL_MEMORY_MODE, DB_USERNAME, DB_PASSWORD);
253+
logger.info("Database connection was successful");
254+
} catch (SQLException e) {
255+
logger.info("Error while getting database connection");
256+
e.printStackTrace();
257+
System.exit(-1);
258+
}
259+
return connection;
260+
}
261+
262+
private void loadDatabaseDriver() {
263+
org.h2.Driver.load();
264+
// try {
265+
// Class.forName("org.h2.Driver");
266+
// } catch (ClassNotFoundException e) {
267+
// e.printStackTrace();
268+
// }
269+
}
270+
271+
private void startH2Server() {
272+
try {
273+
server = Server.createTcpServer("-tcpAllowOthers", "-tcpDaemon");
274+
server.start();
275+
logger.info("Server H2 has started");
276+
} catch (SQLException e) {
277+
e.printStackTrace();
278+
}
279+
}
280+
281+
private void stopH2Server() {
282+
if (server == null) {
283+
return;
284+
}
285+
if (server.isRunning(true)) {
286+
server.stop();
287+
server.shutdown();
288+
logger.info("H2 server has been shut down");
289+
}
290+
}
291+
292+
}

0 commit comments

Comments
 (0)