Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions dao/src/main/java/com/iluwatar/dao/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

import javax.sql.DataSource;

import org.h2.jdbcx.JdbcDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -44,27 +41,25 @@
* application needs, in terms of domain-specific objects and data types (the public interface of
* the DAO), from how these needs can be satisfied with a specific DBMS.
*
* <p>With the DAO pattern, we can use various method calls to retrieve/add/delete/update data
* without directly interacting with the data source. The below example demonstrates basic CRUD
* <p>With the DAO pattern, we can use various method calls to retrieve/add/delete/update data
* without directly interacting with the data source. The below example demonstrates basic CRUD
* operations: select, add, update, and delete.
*
*
*/
public class App {
private static final String DB_URL = "jdbc:h2:~/dao";
private static Logger log = LoggerFactory.getLogger(App.class);
private static final String ALL_CUSTOMERS = "customerDao.getAllCustomers(): ";

/**
* Program entry point.
*
*
* @param args command line args.
* @throws Exception if any error occurs.
* @throws Exception if any error occurs.
*/
public static void main(final String[] args) throws Exception {
final CustomerDao inMemoryDao = new InMemoryCustomerDao();
performOperationsUsing(inMemoryDao);

final DataSource dataSource = createDataSource();
createSchema(dataSource);
final CustomerDao dbDao = new DbCustomerDao(dataSource);
Expand All @@ -74,14 +69,14 @@ public static void main(final String[] args) throws Exception {

private static void deleteSchema(DataSource dataSource) throws SQLException {
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
Statement statement = connection.createStatement()) {
statement.execute(CustomerSchemaSql.DELETE_SCHEMA_SQL);
}
}

private static void createSchema(DataSource dataSource) throws SQLException {
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
Statement statement = connection.createStatement()) {
statement.execute(CustomerSchemaSql.CREATE_SCHEMA_SQL);
}
}
Expand Down Expand Up @@ -121,7 +116,7 @@ private static void addCustomers(CustomerDao customerDao) throws Exception {

/**
* Generate customers.
*
*
* @return list of customers.
*/
public static List<Customer> generateSampleCustomers() {
Expand Down
9 changes: 4 additions & 5 deletions dao/src/main/java/com/iluwatar/dao/CustomException.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,19 @@
package com.iluwatar.dao;

/**
*
* Custom exception
*
* Custom exception.
*/
public class CustomException extends Exception {

private static final long serialVersionUID = 1L;

public CustomException() {}
public CustomException() {
}

public CustomException(String message) {
super(message);
}

public CustomException(String message, Throwable cause) {
super(message, cause);
}
Expand Down
1 change: 0 additions & 1 deletion dao/src/main/java/com/iluwatar/dao/Customer.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

/**
* A customer POJO that represents the data that will be read from the data source.
*
*/
public class Customer {

Expand Down
38 changes: 24 additions & 14 deletions dao/src/main/java/com/iluwatar/dao/CustomerDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,51 +28,61 @@

/**
* In an application the Data Access Object (DAO) is a part of Data access layer. It is an object
* that provides an interface to some type of persistence mechanism. By mapping application calls
* to the persistence layer, DAO provides some specific data operations without exposing details
* of the database. This isolation supports the Single responsibility principle. It separates what
* data accesses the application needs, in terms of domain-specific objects and data types
* (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS,
* database schema, etc.
*
* <p>Any change in the way data is stored and retrieved will not change the client code as the
* that provides an interface to some type of persistence mechanism. By mapping application calls to
* the persistence layer, DAO provides some specific data operations without exposing details of the
* database. This isolation supports the Single responsibility principle. It separates what data
* accesses the application needs, in terms of domain-specific objects and data types (the public
* interface of the DAO), from how these needs can be satisfied with a specific DBMS, database
* schema, etc.
*
* <p>Any change in the way data is stored and retrieved will not change the client code as the
* client will be using interface and need not worry about exact source.
*
*
* @see InMemoryCustomerDao
* @see DbCustomerDao
*/
public interface CustomerDao {

/**
* @return all the customers as a stream. The stream may be lazily or eagerly evaluated based
* on the implementation. The stream must be closed after use.
* Get all customers.
*
* @return all the customers as a stream. The stream may be lazily or eagerly evaluated based on
* the implementation. The stream must be closed after use.
* @throws Exception if any error occurs.
*/
Stream<Customer> getAll() throws Exception;

/**
* Get customer as Optional by id.
*
* @param id unique identifier of the customer.
* @return an optional with customer if a customer with unique identifier <code>id</code>
* exists, empty optional otherwise.
* @return an optional with customer if a customer with unique identifier <code>id</code> exists,
* empty optional otherwise.
* @throws Exception if any error occurs.
*/
Optional<Customer> getById(int id) throws Exception;

/**
* Add a customer.
*
* @param customer the customer to be added.
* @return true if customer is successfully added, false if customer already exists.
* @throws Exception if any error occurs.
*/
boolean add(Customer customer) throws Exception;

/**
* Update a customer.
*
* @param customer the customer to be updated.
* @return true if customer exists and is successfully updated, false otherwise.
* @throws Exception if any error occurs.
*/
boolean update(Customer customer) throws Exception;

/**
* Delete a customer.
*
* @param customer the customer to be deleted.
* @return true if customer exists and is successfully deleted, false otherwise.
* @throws Exception if any error occurs.
Expand Down
10 changes: 6 additions & 4 deletions dao/src/main/java/com/iluwatar/dao/CustomerSchemaSql.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
package com.iluwatar.dao;

/**
* Customer Schema SQL Class
* Customer Schema SQL Class.
*/
public final class CustomerSchemaSql {

private CustomerSchemaSql() {}
private CustomerSchemaSql() {
}

public static final String CREATE_SCHEMA_SQL = "CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), "
+ "LNAME VARCHAR(100))";
public static final String CREATE_SCHEMA_SQL =
"CREATE TABLE CUSTOMERS (ID NUMBER, FNAME VARCHAR(100), "
+ "LNAME VARCHAR(100))";

public static final String DELETE_SCHEMA_SQL = "DROP TABLE CUSTOMERS";

Expand Down
47 changes: 24 additions & 23 deletions dao/src/main/java/com/iluwatar/dao/DbCustomerDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@

package com.iluwatar.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
Expand All @@ -36,12 +33,12 @@
import java.util.function.Consumer;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* An implementation of {@link CustomerDao} that persists customers in RDBMS.
*
*/
public class DbCustomerDao implements CustomerDao {

Expand All @@ -50,29 +47,32 @@ public class DbCustomerDao implements CustomerDao {
private final DataSource dataSource;

/**
* Creates an instance of {@link DbCustomerDao} which uses provided <code>dataSource</code>
* to store and retrieve customer information.
*
* Creates an instance of {@link DbCustomerDao} which uses provided <code>dataSource</code> to
* store and retrieve customer information.
*
* @param dataSource a non-null dataSource.
*/
public DbCustomerDao(DataSource dataSource) {
this.dataSource = dataSource;
}

/**
* @return a lazily populated stream of customers. Note the stream returned must be closed to
* free all the acquired resources. The stream keeps an open connection to the database till
* it is complete or is closed manually.
* Get all customers as Java Stream.
*
* @return a lazily populated stream of customers. Note the stream returned must be closed to free
* all the acquired resources. The stream keeps an open connection to the database till it is
* complete or is closed manually.
*/
@Override
public Stream<Customer> getAll() throws Exception {

Connection connection;
try {
connection = getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS"); // NOSONAR
PreparedStatement statement =
connection.prepareStatement("SELECT * FROM CUSTOMERS"); // NOSONAR
ResultSet resultSet = statement.executeQuery(); // NOSONAR
return StreamSupport.stream(new Spliterators.AbstractSpliterator<Customer>(Long.MAX_VALUE,
return StreamSupport.stream(new Spliterators.AbstractSpliterator<Customer>(Long.MAX_VALUE,
Spliterator.ORDERED) {

@Override
Expand Down Expand Up @@ -108,8 +108,8 @@ private void mutedClose(Connection connection, PreparedStatement statement, Resu
}

private Customer createCustomer(ResultSet resultSet) throws SQLException {
return new Customer(resultSet.getInt("ID"),
resultSet.getString("FNAME"),
return new Customer(resultSet.getInt("ID"),
resultSet.getString("FNAME"),
resultSet.getString("LNAME"));
}

Expand All @@ -122,8 +122,8 @@ public Optional<Customer> getById(int id) throws Exception {
ResultSet resultSet = null;

try (Connection connection = getConnection();
PreparedStatement statement =
connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
PreparedStatement statement =
connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {

statement.setInt(1, id);
resultSet = statement.executeQuery();
Expand Down Expand Up @@ -151,8 +151,8 @@ public boolean add(Customer customer) throws Exception {
}

try (Connection connection = getConnection();
PreparedStatement statement =
connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
PreparedStatement statement =
connection.prepareStatement("INSERT INTO CUSTOMERS VALUES (?,?,?)")) {
statement.setInt(1, customer.getId());
statement.setString(2, customer.getFirstName());
statement.setString(3, customer.getLastName());
Expand All @@ -169,8 +169,9 @@ public boolean add(Customer customer) throws Exception {
@Override
public boolean update(Customer customer) throws Exception {
try (Connection connection = getConnection();
PreparedStatement statement =
connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
PreparedStatement statement =
connection
.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
statement.setString(1, customer.getFirstName());
statement.setString(2, customer.getLastName());
statement.setInt(3, customer.getId());
Expand All @@ -186,8 +187,8 @@ public boolean update(Customer customer) throws Exception {
@Override
public boolean delete(Customer customer) throws Exception {
try (Connection connection = getConnection();
PreparedStatement statement =
connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
PreparedStatement statement =
connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
statement.setInt(1, customer.getId());
return statement.executeUpdate() > 0;
} catch (SQLException ex) {
Expand Down
6 changes: 3 additions & 3 deletions dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
import java.util.stream.Stream;

/**
* An in memory implementation of {@link CustomerDao}, which stores the customers in JVM memory
* and data is lost when the application exits.
* An in memory implementation of {@link CustomerDao}, which stores the customers in JVM memory and
* data is lost when the application exits.
* <br>
* This implementation is useful as temporary database or for testing.
*/
Expand All @@ -56,7 +56,7 @@ public boolean add(final Customer customer) {
if (getById(customer.getId()).isPresent()) {
return false;
}

idToCustomer.put(customer.getId(), customer);
return true;
}
Expand Down
Loading