-
-
Notifications
You must be signed in to change notification settings - Fork 27k
DAO Factory pattern for Issue #1270 #2105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would only suggest to change that switch case statement, unless you have a fair position to have it like that
dao-factory/src/main/java/com/iluwatar/daofactory/DAOFactory.java
Outdated
Show resolved
Hide resolved
dao-factory/src/main/java/com/iluwatar/daofactory/DAOFactory.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thank you, @rrreynaldo! |
Hi @burno1, thanks for the review and I agree that enum would be a neater implementation. Just made the changes and Thanks a lot! |
Kudos, SonarCloud Quality Gate passed! |
This closes #1270 |
@rrreynaldo, add the issue to the description of the PR, so we can have the two linked |
@burno1 Done! |
layout: pattern | ||
title: Data Access Object Factory (DAO Factory) | ||
folder: dao-factory | ||
permalink: /patterns/dao-factory/ | ||
categories: Architectural | ||
language: en | ||
tags: | ||
- Data access |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check out the updated yaml frontmatter requirements at https://github.com/iluwatar/java-design-patterns/wiki/01.-How-to-contribute. In essence, you can drop some of the tags here.
|
||
DAO Factory is a design pattern which utilise the Abstract Factory and Factory Method to create and produce a new instance of DAOs that are needed by the client application by creating a concrete Factory for a specific data source type. | ||
|
||
## Explanation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, please add here the standard items
- real world example
- in plain words
- wikipedia (or some other authoritative source) says
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-api</artifactId> | ||
<version>5.8.1</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the version from the parent pom.xml
public int getId() { | ||
return id; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Lombok where possible to reduce boilerplate
/** | ||
* An implementation example for a client code | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain the pattern briefly and how this example code implements it.
// Connection variable information to Postgres database | ||
private static final String conn = "jdbc:postgresql://localhost:5432/dao_factory"; | ||
private static final String user = "postgres"; | ||
private static final String pass = "123"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understood correctly, running the example requires that a local PostgreSQL database server is running? Usually what we do is use an in-memory database (like H2) by default and then it's possible to configure the code to use an external database, but not required.
e.printStackTrace(); | ||
System.err.println(e.getClass().getName()+": "+e.getMessage()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use logger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check this throughout the code
@Test | ||
void testInsertOrder() { | ||
Method method = null; | ||
try { | ||
method = PostgresOrderDAO.class.getMethod("insertOrder", String.class, String.class, String.class); | ||
} catch (NoSuchMethodException e) { | ||
e.printStackTrace(); | ||
} | ||
assertNotNull(method); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see much value in this kind of reflection-based tests
Order template = new Order(); | ||
Connection con = PostgresDAOFactory.createConnection(); | ||
Statement stmt; | ||
ResultSet rs; | ||
String sql = "SELECT * FROM orders WHERE ("; | ||
boolean firstCondition = true; | ||
|
||
// Combining the query with the variable value depending on the | ||
// attribute that has been passed to the function | ||
if (senderName == null && rcvrName == null && destination == null) { | ||
return template; | ||
} | ||
// Combining the senderName attribute | ||
if (senderName != null && !senderName.equals("")) { | ||
senderName = "'" + senderName + "'"; | ||
sql += "sender_name = " +senderName; | ||
firstCondition = false; | ||
} | ||
// Combining the receiverName attribute | ||
if (rcvrName != null && !rcvrName.equals("")) { | ||
rcvrName = "'" + rcvrName + "'"; | ||
if (firstCondition) { | ||
sql += "receiver_name = " + rcvrName; | ||
firstCondition = false; | ||
} else { | ||
sql += " AND receiver_name = " + rcvrName; | ||
} | ||
} | ||
// Combining the destination attribute | ||
if (destination != null && !destination.equals("")) { | ||
destination = "'" + destination + "'"; | ||
if (firstCondition) { | ||
sql += "destination = " + destination; | ||
} else { | ||
sql += " AND destination = " + destination; | ||
} | ||
} | ||
// Closing the sql statement | ||
sql += ");"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
General note about this kind of SQL query building using string concatenation
- High risk of SQL injection if you accidentally concatenate user input to your SQL queries
- Difficult to avoid syntax errors in non-trivial cases, when dynamic SQL gets more complex
I would recommend using JPA criteria queries or jOOQ to make the code cleaner and safer.
public enum DataSourceType { | ||
POSTGRES // And other data source type | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could have here another data source H2
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Closed due to inactivity |
Closes #1270