diff --git a/README.md b/README.md
index 3f95f02..2e3670a 100644
--- a/README.md
+++ b/README.md
@@ -190,4 +190,6 @@ using prepared statement.
- [Accessing Databases Through JDBC with Java](https://app.pluralsight.com/projects/accessing-databases-through-jdbc-in-java)
- [Design_Patterns_In_Java_CRUD](https://github.com/naman14310/Design_Patterns_In_Java_CRUD)
- [Database Normalization](http://extreme-java.blogspot.com/2014/05/database-normalization.html)
-- [Database Interaction with DAO and DTO Design Patterns](https://dzone.com/articles/database-interaction-dao-and)
\ No newline at end of file
+- [Database Interaction with DAO and DTO Design Patterns](https://dzone.com/articles/database-interaction-dao-and)
+- [`try`-with-resources](https://en.wikipedia.org/wiki/Java_syntax#try-with-resources_statements)
+- [tryResourceClose](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 915dc3e..296a541 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,11 +61,36 @@
org.jetbrains
annotations
- RELEASE
+ 23.1.0
compile
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.19.0
+
+
+
+ pmd-ruleset.xml
+
+
+
+
+
+
+
orders
@@ -97,6 +122,32 @@
maven-surefire-plugin
2.22.2
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.19.0
+
+
+ true
+
+ true
+
+
+
+ pmd-ruleset.xml
+
+
+
+
+
+ pmd-check
+ verify
+
+ check
+
+
+
+
diff --git a/src/main/java/com/example/order/Main.java b/src/main/java/com/example/order/Main.java
index 9561573..689fced 100644
--- a/src/main/java/com/example/order/Main.java
+++ b/src/main/java/com/example/order/Main.java
@@ -13,6 +13,7 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -32,11 +33,10 @@ public class Main {
*
* @param args Command and arguments to be interpreted by the application
*/
- public static void main(String[] args) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- String command = "";
+ public static void main(String[] args) throws SQLException, IOException {
- try {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ String command = "";
while (!Commands.EXIT.getCmd().equalsIgnoreCase(command)) {
System.out.print(INITIAL_PROMPT);
String line = reader.readLine();
@@ -63,7 +63,7 @@ public static void main(String[] args) {
*
* @param args Arguments given to the application
*/
- private static void processCommand(String[] args) {
+ private static void processCommand(String[] args) throws SQLException, IOException {
String error = validateArgs(args);
if (isEmpty(error)) {
@@ -120,10 +120,9 @@ private static void processCommand(String[] args) {
*/
private static @NotNull OrderDto askForOrderDetails() {
OrderDto orderDTO = new OrderDto();
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- boolean invalidInput;
- try {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ boolean invalidInput;
/* Ask for customer ID */
do {
System.out.print("Customer ID: ");
@@ -141,7 +140,7 @@ private static void processCommand(String[] args) {
do {
OrderDetailDto orderDetailDTO = new OrderDetailDto();
- // Ask for product ID
+ /* Ask for product ID */
do {
System.out.print("Product ID: ");
String line = reader.readLine();
diff --git a/src/main/java/com/example/order/dao/DeleteOrderDao.java b/src/main/java/com/example/order/dao/DeleteOrderDao.java
index 2e30d9d..a8246cb 100644
--- a/src/main/java/com/example/order/dao/DeleteOrderDao.java
+++ b/src/main/java/com/example/order/dao/DeleteOrderDao.java
@@ -5,6 +5,7 @@
import com.example.order.util.ExceptionHandler;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@@ -32,7 +33,7 @@ public DeleteOrderDao(Database database) {
* @param paramsDto Object with the parameters for the operation
* @return Number of orders deleted
*/
- public int deleteOrdersById(@NotNull ParamsDto paramsDto) {
+ public int deleteOrdersById(@NotNull ParamsDto paramsDto) throws IOException {
int numberResults = 0;
try (Connection con = database.getConnection();
diff --git a/src/main/java/com/example/order/dao/GetOrderDao.java b/src/main/java/com/example/order/dao/GetOrderDao.java
index 36dafef..b5ffe79 100644
--- a/src/main/java/com/example/order/dao/GetOrderDao.java
+++ b/src/main/java/com/example/order/dao/GetOrderDao.java
@@ -6,6 +6,7 @@
import com.example.order.util.ExceptionHandler;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -16,7 +17,7 @@
* DAO to get an order
*/
public class GetOrderDao {
- private final String query = "SELECT * FROM orders o WHERE o.order_id = ?";
+ private final static String query = "SELECT * FROM orders o WHERE o.order_id = ?";
private final Database database;
/**
@@ -53,8 +54,8 @@ public OrderDto getOrderById(ParamsDto paramsDto) {
orderDto.setStatus(rs.getString(4));
}
- } catch (SQLException ex) {
- ExceptionHandler.handleException(ex);
+ } catch (SQLException | IOException ex) {
+ ExceptionHandler.handleException((SQLException) ex);
}
return orderDto;
diff --git a/src/main/java/com/example/order/dao/InsertOrderDao.java b/src/main/java/com/example/order/dao/InsertOrderDao.java
index 4fd9002..2e324dd 100644
--- a/src/main/java/com/example/order/dao/InsertOrderDao.java
+++ b/src/main/java/com/example/order/dao/InsertOrderDao.java
@@ -7,6 +7,7 @@
import com.example.order.util.OrderStatus;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
import java.sql.*;
import java.time.LocalDateTime;
@@ -38,7 +39,7 @@ public InsertOrderDao(Database database) {
* @param orderDto Object with the information to insert
* @return The ID of the order inserted
*/
- public long insertOrder(OrderDto orderDto) {
+ public long insertOrder(OrderDto orderDto) throws IOException {
long orderId = -1;
try (Connection con = database.getConnection();
diff --git a/src/main/java/com/example/order/dao/TotalOrderDao.java b/src/main/java/com/example/order/dao/TotalOrderDao.java
index fcfc766..9f457dc 100644
--- a/src/main/java/com/example/order/dao/TotalOrderDao.java
+++ b/src/main/java/com/example/order/dao/TotalOrderDao.java
@@ -5,6 +5,7 @@
import com.example.order.util.ExceptionHandler;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
import java.math.BigDecimal;
import java.sql.*;
@@ -12,7 +13,7 @@
* DAO to get the total of all the paid orders of a customer
*/
public class TotalOrderDao {
- private final String query = "{call GET_PAID_ORDER_TOTAL_FROM_CUSTOMER(?)}";
+ private final static String query = "{call GET_PAID_ORDER_TOTAL_FROM_CUSTOMER(?)}";
private final Database database;
/**
@@ -30,7 +31,7 @@ public TotalOrderDao(Database database) {
* @param paramsDto Object with the arguments of the operation
* @return Total of all paid orders
*/
- public BigDecimal getTotalAllPaidOrders(ParamsDto paramsDto) {
+ public BigDecimal getTotalAllPaidOrders(ParamsDto paramsDto) throws SQLException, IOException {
BigDecimal result = null;
try (Connection con = database.getConnection();
diff --git a/src/main/java/com/example/order/dao/UpdateOrderDao.java b/src/main/java/com/example/order/dao/UpdateOrderDao.java
index 8e83b45..44966f6 100644
--- a/src/main/java/com/example/order/dao/UpdateOrderDao.java
+++ b/src/main/java/com/example/order/dao/UpdateOrderDao.java
@@ -5,6 +5,7 @@
import com.example.order.util.ExceptionHandler;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@@ -13,7 +14,6 @@
* DAO to update an order
*/
public class UpdateOrderDao {
- private final String query = "UPDATE orders o SET o.order_status = ? WHERE o.order_id = ?";
private final Database database;
/**
@@ -31,7 +31,7 @@ public UpdateOrderDao(Database database) {
* @param paramsDto Object with the parameters for the operation
* @return Number of affected rows
*/
- public int updateOrderStatus(ParamsDto paramsDto) {
+ public int updateOrderStatus(ParamsDto paramsDto) throws IOException {
int numberResults = 0;
try (Connection con = database.getConnection();
@@ -55,6 +55,7 @@ public int updateOrderStatus(ParamsDto paramsDto) {
* @throws SQLException In case of an error
*/
private @NotNull PreparedStatement createPreparedStatement(@NotNull Connection con, @NotNull ParamsDto paramsDto) throws SQLException {
+ String query = "UPDATE orders o SET o.order_status = ? WHERE o.order_id = ?";
PreparedStatement ps = con.prepareStatement(query);
ps.setString(1, paramsDto.getStatus());
ps.setLong(2, paramsDto.getOrderId());
diff --git a/src/main/java/com/example/order/service/DeleteOrderService.java b/src/main/java/com/example/order/service/DeleteOrderService.java
index 043a3bd..cd860fa 100644
--- a/src/main/java/com/example/order/service/DeleteOrderService.java
+++ b/src/main/java/com/example/order/service/DeleteOrderService.java
@@ -4,6 +4,8 @@
import com.example.order.dto.ParamsDto;
import com.example.order.util.Database;
+import java.io.IOException;
+
/**
* Service class to delete one or more orders
*/
@@ -16,7 +18,7 @@ public class DeleteOrderService implements OrderService {
* @param paramsDTO Object with the parameters to execute the service
*/
@Override
- public String execute(ParamsDto paramsDTO) {
+ public String execute(ParamsDto paramsDTO) throws IOException {
String result;
int rowsAffected = deleteOrderDao.deleteOrdersById(paramsDTO);
diff --git a/src/main/java/com/example/order/service/InsertOrderService.java b/src/main/java/com/example/order/service/InsertOrderService.java
index 53cf3e7..d8c1481 100644
--- a/src/main/java/com/example/order/service/InsertOrderService.java
+++ b/src/main/java/com/example/order/service/InsertOrderService.java
@@ -5,6 +5,8 @@
import com.example.order.util.Database;
import org.jetbrains.annotations.NotNull;
+import java.io.IOException;
+
/**
* Service class to insert an order
*/
@@ -17,7 +19,7 @@ public class InsertOrderService implements OrderService {
* @param paramsDTO Object with the parameters to execute the service
*/
@Override
- public String execute(@NotNull ParamsDto paramsDTO) {
+ public String execute(@NotNull ParamsDto paramsDTO) throws IOException {
String result;
long orderId = insertOrderDao.insertOrder(paramsDTO.getOrder());
diff --git a/src/main/java/com/example/order/service/OrderService.java b/src/main/java/com/example/order/service/OrderService.java
index 43b47fb..ff62763 100644
--- a/src/main/java/com/example/order/service/OrderService.java
+++ b/src/main/java/com/example/order/service/OrderService.java
@@ -2,9 +2,12 @@
import com.example.order.dto.ParamsDto;
+import java.io.IOException;
+import java.sql.SQLException;
+
/**
* Interface for service classes
*/
public interface OrderService {
- String execute(ParamsDto paramsDTO);
+ String execute(ParamsDto paramsDTO) throws IOException, SQLException;
}
diff --git a/src/main/java/com/example/order/service/TotalOrderService.java b/src/main/java/com/example/order/service/TotalOrderService.java
index 984e6a8..9d89de6 100644
--- a/src/main/java/com/example/order/service/TotalOrderService.java
+++ b/src/main/java/com/example/order/service/TotalOrderService.java
@@ -4,7 +4,9 @@
import com.example.order.dto.ParamsDto;
import com.example.order.util.Database;
+import java.io.IOException;
import java.math.BigDecimal;
+import java.sql.SQLException;
/**
* Service class to get the total of the orders of a customer
@@ -18,7 +20,7 @@ public class TotalOrderService implements OrderService {
* @param paramsDTO Object with the parameters to execute the service
*/
@Override
- public String execute(ParamsDto paramsDTO) {
+ public String execute(ParamsDto paramsDTO) throws IOException, SQLException {
String result;
BigDecimal total = totalOrderDao.getTotalAllPaidOrders(paramsDTO);
diff --git a/src/main/java/com/example/order/service/UpdateOrderService.java b/src/main/java/com/example/order/service/UpdateOrderService.java
index fac31b5..b3954ec 100644
--- a/src/main/java/com/example/order/service/UpdateOrderService.java
+++ b/src/main/java/com/example/order/service/UpdateOrderService.java
@@ -4,6 +4,8 @@
import com.example.order.dto.ParamsDto;
import com.example.order.util.Database;
+import java.io.IOException;
+
/**
* Service class to update an order
*/
@@ -16,7 +18,7 @@ public class UpdateOrderService implements OrderService {
* @param paramsDTO Object with the parameters to execute the service
*/
@Override
- public String execute(ParamsDto paramsDTO) {
+ public String execute(ParamsDto paramsDTO) throws IOException {
String result;
int rowsAffected = updateOrderDao.updateOrderStatus(paramsDTO);
diff --git a/src/main/java/com/example/order/util/Database.java b/src/main/java/com/example/order/util/Database.java
index f069082..30366c1 100644
--- a/src/main/java/com/example/order/util/Database.java
+++ b/src/main/java/com/example/order/util/Database.java
@@ -2,6 +2,7 @@
import org.h2.tools.RunScript;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
@@ -10,14 +11,16 @@
/**
* Singleton class to get database connections
+ *
+ * @link https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
*/
public class Database {
private static Database instance = null;
private static boolean isInitialized = false;
- private final String url = "jdbc:h2:mem:orders;DB_CLOSE_DELAY=-1";
- private final String user = "sa";
- private final String password = "";
+ private static final String url = "jdbc:h2:mem:orders;DB_CLOSE_DELAY=-1";
+ private static final String user = "sa";
+ private static final String password = "";
/**
* Private constructor
@@ -25,6 +28,10 @@ public class Database {
private Database() {
}
+ private static class LazyHolder {
+ static final Database INSTANCE = new Database();
+ }
+
/**
* Method that creates an instance of this class (if it's not created already)
*
@@ -32,7 +39,7 @@ private Database() {
*/
public static Database getInstance() {
if (instance == null) {
- instance = new Database();
+ instance = LazyHolder.INSTANCE;
}
return instance;
}
@@ -42,7 +49,7 @@ public static Database getInstance() {
*
* @param connection Object that represents a connection to the database
*/
- private static void initializeDatabase(Connection connection) {
+ private static void initializeDatabase(Connection connection) throws IOException {
try {
InputStream is = Database.class.getResourceAsStream("/db.sql");
assert is != null;
@@ -58,7 +65,7 @@ private static void initializeDatabase(Connection connection) {
* @return A connection object
* @throws SQLException In case of a database error
*/
- public Connection getConnection() throws SQLException {
+ public Connection getConnection() throws SQLException, IOException {
Connection connection = DriverManager.getConnection(url, user, password);
if (!isInitialized && connection != null) {
diff --git a/src/main/java/com/example/order/util/ExceptionHandler.java b/src/main/java/com/example/order/util/ExceptionHandler.java
index 1befdbb..57d9f0d 100644
--- a/src/main/java/com/example/order/util/ExceptionHandler.java
+++ b/src/main/java/com/example/order/util/ExceptionHandler.java
@@ -1,7 +1,5 @@
package com.example.order.util;
-import org.jetbrains.annotations.NotNull;
-
import java.sql.SQLException;
/**
@@ -14,7 +12,7 @@ public class ExceptionHandler {
*
* @param sqlException Exception from which information will be extracted
*/
- public static void handleException(@NotNull SQLException sqlException) {
+ public static void handleException(SQLException sqlException) {
System.out.println(sqlException.getErrorCode());
System.out.println(sqlException.getSQLState());
System.out.println(sqlException.getMessage());
diff --git a/src/main/java/com/example/order/util/H2StoredProcedures.java b/src/main/java/com/example/order/util/H2StoredProcedures.java
index c3e4dad..f82b5ff 100644
--- a/src/main/java/com/example/order/util/H2StoredProcedures.java
+++ b/src/main/java/com/example/order/util/H2StoredProcedures.java
@@ -27,8 +27,10 @@ public static ResultSet getPaidOrderTotalFromCustomer(@NotNull Connection conn,
PreparedStatement ps = conn.prepareStatement(sql.toString());
ResultSet results = ps.executeQuery();
- while (results.next())
+
+ while (results.next()) {
joiner.add(results.getString("order_id"));
+ }
sql = new StringBuilder();
sql.append("SELECT SUM( MULT(product_price, order_detail_quantity) ) FROM order_details, products ");
diff --git a/src/test/java/com/example/order/DatabaseTest.java b/src/test/java/com/example/order/DatabaseTest.java
index 7797155..d0f4ed4 100644
--- a/src/test/java/com/example/order/DatabaseTest.java
+++ b/src/test/java/com/example/order/DatabaseTest.java
@@ -100,8 +100,7 @@ public void shouldUseDriverManagerToConnectToDB() {
con.close();
} catch (Exception e) {
//e.printStackTrace();
- assertTrue("The connection is not valid. The method `getConnection()` threw an exception. Make sure you're opening the connection with the right parameters.",
- false);
+ fail("The connection is not valid. The method `getConnection()` threw an exception. Make sure you're opening the connection with the right parameters.");
}
}
}
diff --git a/src/test/java/com/example/order/DeleteOrderDaoTest.java b/src/test/java/com/example/order/DeleteOrderDaoTest.java
index 52b7fde..a8ee97e 100644
--- a/src/test/java/com/example/order/DeleteOrderDaoTest.java
+++ b/src/test/java/com/example/order/DeleteOrderDaoTest.java
@@ -1,5 +1,6 @@
package com.example.order;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
@@ -54,7 +55,7 @@ public void setup() {
}
@Test
- public void shouldCreateDatabaseConnection() throws SQLException {
+ public void shouldCreateDatabaseConnection() throws SQLException, IOException {
Database databaseMock = Mockito.mock(Database.class);
when(databaseMock.getConnection()).thenReturn(databaseInstance.getConnection());
diff --git a/src/test/java/com/example/order/GetOrderDaoTest.java b/src/test/java/com/example/order/GetOrderDaoTest.java
index 008860f..5f72a0c 100644
--- a/src/test/java/com/example/order/GetOrderDaoTest.java
+++ b/src/test/java/com/example/order/GetOrderDaoTest.java
@@ -1,5 +1,6 @@
package com.example.order;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -35,7 +36,7 @@ public void setup() {
}
@Test
- public void shouldCreateDatabaseConnection() throws SQLException {
+ public void shouldCreateDatabaseConnection() throws SQLException, IOException {
when(databaseMock.getConnection()).thenReturn(databaseInstance.getConnection());
GetOrderDao getOrderDao = new GetOrderDao(databaseMock);
diff --git a/src/test/java/com/example/order/InsertOrderDaoTest.java b/src/test/java/com/example/order/InsertOrderDaoTest.java
index 54f272b..f034165 100644
--- a/src/test/java/com/example/order/InsertOrderDaoTest.java
+++ b/src/test/java/com/example/order/InsertOrderDaoTest.java
@@ -1,5 +1,6 @@
package com.example.order;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
@@ -54,7 +55,7 @@ public void setup() {
}
@Test
- public void shouldGetConnectionObject() throws SQLException {
+ public void shouldGetConnectionObject() throws SQLException, IOException {
Database databaseMock = Mockito.mock(Database.class);
when(databaseMock.getConnection()).thenReturn(databaseInstance.getConnection());
diff --git a/src/test/java/com/example/order/TotalOrderDaoTest.java b/src/test/java/com/example/order/TotalOrderDaoTest.java
index 0aee472..d6dc884 100644
--- a/src/test/java/com/example/order/TotalOrderDaoTest.java
+++ b/src/test/java/com/example/order/TotalOrderDaoTest.java
@@ -1,5 +1,6 @@
package com.example.order;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
@@ -49,7 +50,7 @@ public void setup() {
}
@Test
- public void shouldGetConnectionObject() throws SQLException {
+ public void shouldGetConnectionObject() throws SQLException, IOException {
Database databaseMock = Mockito.mock(Database.class);
when(databaseMock.getConnection()).thenReturn(databaseInstance.getConnection());
diff --git a/src/test/java/com/example/order/UpdateOrderDaoTest.java b/src/test/java/com/example/order/UpdateOrderDaoTest.java
index b7bf8c0..f8d78e1 100644
--- a/src/test/java/com/example/order/UpdateOrderDaoTest.java
+++ b/src/test/java/com/example/order/UpdateOrderDaoTest.java
@@ -1,5 +1,6 @@
package com.example.order;
+import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
@@ -52,7 +53,7 @@ public void setup() {
}
@Test
- public void shouldCreateDatabaseConnection() throws SQLException {
+ public void shouldCreateDatabaseConnection() throws SQLException, IOException {
Database databaseMock = Mockito.mock(Database.class);
when(databaseMock.getConnection()).thenReturn(databaseInstance.getConnection());