Skip to content

Commit fa077c8

Browse files
committed
Work on iluwatar#404, javadocs and test cases for DB and in memory dao.
1 parent 448d855 commit fa077c8

File tree

8 files changed

+335
-203
lines changed

8 files changed

+335
-203
lines changed

dao/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
<groupId>de.bechte.junit</groupId>
5353
<artifactId>junit-hierarchicalcontextrunner</artifactId>
5454
</dependency>
55+
<dependency>
56+
<groupId>org.mockito</groupId>
57+
<artifactId>mockito-core</artifactId>
58+
</dependency>
5559
</dependencies>
5660

5761
<build>

dao/src/main/java/com/iluwatar/dao/App.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ public class App {
4949
* Program entry point.
5050
*
5151
* @param args command line args.
52+
* @throws Exception if any error occurs.
5253
*/
53-
public static void main(final String[] args) {
54-
final CustomerDao customerDao = new InMemoryCustomerDao(generateSampleCustomers());
54+
public static void main(final String[] args) throws Exception {
55+
final CustomerDao customerDao = new InMemoryCustomerDao();
56+
addCustomers(customerDao);
5557
log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
5658
log.info("customerDao.getCusterById(2): " + customerDao.getById(2));
5759
final Customer customer = new Customer(4, "Dan", "Danson");
@@ -65,6 +67,12 @@ public static void main(final String[] args) {
6567
log.info("customerDao.getAllCustomers(): " + customerDao.getAll());
6668
}
6769

70+
private static void addCustomers(CustomerDao customerDao) throws Exception {
71+
for (Customer customer : generateSampleCustomers()) {
72+
customerDao.add(customer);
73+
}
74+
}
75+
6876
/**
6977
* Generate customers.
7078
*

dao/src/main/java/com/iluwatar/dao/CustomerDao.java

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,54 @@
2626

2727
/**
2828
*
29-
* CustomerDao
30-
*
29+
* In an application the Data Access Object (DAO) is a part of Data access layer. It is an object
30+
* that provides an interface to some type of persistence mechanism. By mapping application calls
31+
* to the persistence layer, DAO provides some specific data operations without exposing details
32+
* of the database. This isolation supports the Single responsibility principle. It separates what
33+
* data accesses the application needs, in terms of domain-specific objects and data types
34+
* (the public interface of the DAO), from how these needs can be satisfied with a specific DBMS,
35+
* database schema, etc.
36+
* <br/><br/>
37+
* Any change in the way data is stored and retrieved will not change the client code as the client
38+
* will be using interface and need not worry about exact source.
39+
*
40+
* @see InMemoryCustomerDao
41+
* @see DBCustomerDao
3142
*/
3243
public interface CustomerDao {
3344

34-
Stream<Customer> getAll();
35-
36-
Customer getById(int id);
45+
/**
46+
* @return all the customers as a stream. The stream may be lazily or eagerly evaluated based on the
47+
* implementation. The stream must be closed after use.
48+
* @throws Exception if any error occurs.
49+
*/
50+
Stream<Customer> getAll() throws Exception;
51+
52+
/**
53+
* @param id unique identifier of the customer.
54+
* @return customer with unique identifier <code>id</code> is found, null otherwise.
55+
* @throws Exception if any error occurs.
56+
*/
57+
Customer getById(int id) throws Exception;
3758

38-
boolean add(Customer customer);
59+
/**
60+
* @param customer the customer to be added.
61+
* @return true if customer is successfully added, false if customer already exists.
62+
* @throws Exception if any error occurs.
63+
*/
64+
boolean add(Customer customer) throws Exception;
3965

40-
boolean update(Customer customer);
66+
/**
67+
* @param customer the customer to be updated.
68+
* @return true if customer exists and is successfully updated, false otherwise.
69+
* @throws Exception if any error occurs.
70+
*/
71+
boolean update(Customer customer) throws Exception;
4172

42-
boolean delete(Customer customer);
73+
/**
74+
* @param customer the customer to be deleted.
75+
* @return true if customer exists and is successfully deleted, false otherwise.
76+
* @throws Exception if any error occurs.
77+
*/
78+
boolean delete(Customer customer) throws Exception;
4379
}

dao/src/main/java/com/iluwatar/dao/DBCustomerDao.java

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
1+
/**
2+
* The MIT License
3+
* Copyright (c) 2014 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
123
package com.iluwatar.dao;
224

325
import java.sql.Connection;
4-
import java.sql.DriverManager;
526
import java.sql.PreparedStatement;
627
import java.sql.ResultSet;
728
import java.sql.SQLException;
@@ -11,16 +32,22 @@
1132
import java.util.stream.Stream;
1233
import java.util.stream.StreamSupport;
1334

35+
import javax.sql.DataSource;
36+
37+
/**
38+
*
39+
*
40+
*/
1441
public class DBCustomerDao implements CustomerDao {
1542

16-
private String dbUrl;
43+
private final DataSource dataSource;
1744

18-
public DBCustomerDao(String dbUrl) {
19-
this.dbUrl = dbUrl;
45+
public DBCustomerDao(DataSource dataSource) {
46+
this.dataSource = dataSource;
2047
}
2148

2249
@Override
23-
public Stream<Customer> getAll() {
50+
public Stream<Customer> getAll() throws Exception {
2451

2552
Connection connection;
2653
try {
@@ -41,14 +68,16 @@ public boolean tryAdvance(Consumer<? super Customer> action) {
4168
e.printStackTrace();
4269
return false;
4370
}
44-
4571
}}, false).onClose(() -> mutedClose(connection));
4672
} catch (SQLException e) {
47-
e.printStackTrace();
48-
return null;
73+
throw new Exception(e.getMessage(), e);
4974
}
5075
}
5176

77+
private Connection getConnection() throws SQLException {
78+
return dataSource.getConnection();
79+
}
80+
5281
private void mutedClose(Connection connection) {
5382
try {
5483
connection.close();
@@ -64,22 +93,23 @@ private Customer createCustomer(ResultSet resultSet) throws SQLException {
6493
}
6594

6695
@Override
67-
public Customer getById(int id) {
96+
public Customer getById(int id) throws Exception {
6897
try (Connection connection = getConnection();
6998
PreparedStatement statement = connection.prepareStatement("SELECT * FROM CUSTOMERS WHERE ID = ?")) {
7099
statement.setInt(1, id);
71100
ResultSet resultSet = statement.executeQuery();
72101
if (resultSet.next()) {
73102
return createCustomer(resultSet);
103+
} else {
104+
return null;
74105
}
75106
} catch (SQLException ex) {
76-
ex.printStackTrace();
107+
throw new Exception(ex.getMessage(), ex);
77108
}
78-
return null;
79109
}
80110

81111
@Override
82-
public boolean add(Customer customer) {
112+
public boolean add(Customer customer) throws Exception {
83113
if (getById(customer.getId()) != null) {
84114
return false;
85115
}
@@ -92,39 +122,31 @@ public boolean add(Customer customer) {
92122
statement.execute();
93123
return true;
94124
} catch (SQLException ex) {
95-
ex.printStackTrace();
96-
return false;
125+
throw new Exception(ex.getMessage(), ex);
97126
}
98127
}
99128

100129
@Override
101-
public boolean update(Customer customer) {
130+
public boolean update(Customer customer) throws Exception {
102131
try (Connection connection = getConnection();
103132
PreparedStatement statement = connection.prepareStatement("UPDATE CUSTOMERS SET FNAME = ?, LNAME = ? WHERE ID = ?")) {
104133
statement.setString(1, customer.getFirstName());
105134
statement.setString(2, customer.getLastName());
106135
statement.setInt(3, customer.getId());
107136
return statement.executeUpdate() > 0;
108137
} catch (SQLException ex) {
109-
ex.printStackTrace();
110-
return false;
138+
throw new Exception(ex.getMessage(), ex);
111139
}
112140
}
113141

114142
@Override
115-
public boolean delete(Customer customer) {
143+
public boolean delete(Customer customer) throws Exception {
116144
try (Connection connection = getConnection();
117145
PreparedStatement statement = connection.prepareStatement("DELETE FROM CUSTOMERS WHERE ID = ?")) {
118146
statement.setInt(1, customer.getId());
119147
return statement.executeUpdate() > 0;
120148
} catch (SQLException ex) {
121-
ex.printStackTrace();
122-
return false;
149+
throw new Exception(ex.getMessage(), ex);
123150
}
124151
}
125-
126-
private Connection getConnection() throws SQLException {
127-
return DriverManager.getConnection(dbUrl);
128-
}
129-
130152
}

dao/src/main/java/com/iluwatar/dao/InMemoryCustomerDao.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,22 @@
2323
package com.iluwatar.dao;
2424

2525
import java.util.HashMap;
26-
import java.util.List;
2726
import java.util.Map;
2827
import java.util.stream.Stream;
2928

3029
/**
31-
*
32-
* The data access object (DAO) is an object that provides an abstract interface to some type of
33-
* database or other persistence mechanism. By mapping application calls to the persistence layer,
34-
* DAO provide some specific data operations without exposing details of the database. This
35-
* isolation supports the Single responsibility principle. It separates what data accesses the
36-
* application needs, in terms of domain-specific objects and data types (the public interface of
37-
* the DAO), from how these needs can be satisfied with a specific DBMS, database schema, etc.
38-
*
30+
* An in memory implementation of {@link CustomerDao}, which stores the customers in JVM memory
31+
* and data is lost when the application exits.
32+
* <br/>
33+
* This implementation is useful as temporary database or for testing.
3934
*/
40-
// TODO update the javadoc
4135
public class InMemoryCustomerDao implements CustomerDao {
4236

4337
private Map<Integer, Customer> idToCustomer = new HashMap<>();
4438

45-
public InMemoryCustomerDao(final List<Customer> customers) {
46-
customers.stream()
47-
.forEach((customer) -> idToCustomer.put(customer.getId(), customer));
48-
}
49-
39+
/**
40+
* An eagerly evaluated stream of customers stored in memory.
41+
*/
5042
@Override
5143
public Stream<Customer> getAll() {
5244
return idToCustomer.values().stream();
@@ -67,7 +59,6 @@ public boolean add(final Customer customer) {
6759
return true;
6860
}
6961

70-
7162
@Override
7263
public boolean update(final Customer customer) {
7364
return idToCustomer.replace(customer.getId(), customer) != null;

dao/src/test/java/com/iluwatar/dao/AppTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,12 @@
2424

2525
import org.junit.Test;
2626

27-
import java.io.IOException;
28-
2927
/**
3028
* Tests that DAO example runs without errors.
3129
*/
3230
public class AppTest {
3331
@Test
34-
public void test() throws IOException {
32+
public void test() throws Exception {
3533
String[] args = {};
3634
App.main(args);
3735
}

0 commit comments

Comments
 (0)