diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactory.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactory.java new file mode 100644 index 0000000000..adbdc66030 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactory.java @@ -0,0 +1,23 @@ +package com.baeldung.statmentVsPreparedstatment; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class DatasourceFactory { + + private Connection connection; + + public Connection getConnection() throws ClassNotFoundException, SQLException { + Class.forName("org.h2.Driver"); + connection = DriverManager.getConnection("jdbc:h2:mem:db_basic", "SA", ""); + connection.setAutoCommit(false); + return connection; + } + + public boolean createTables() throws SQLException { + String query = "create table if not exists PERSONS (ID INT, NAME VARCHAR(45))"; + return connection.createStatement().executeUpdate(query) == 0; + } + +} diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PersonEntity.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PersonEntity.java new file mode 100644 index 0000000000..72fc0c1e24 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PersonEntity.java @@ -0,0 +1,42 @@ +package com.baeldung.statmentVsPreparedstatment; + +import java.util.Objects; + +public class PersonEntity { + private int id; + private String name; + + public PersonEntity(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + PersonEntity that = (PersonEntity) o; + return id == that.id && Objects.equals(name, that.name); + } + + @Override public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDao.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDao.java new file mode 100644 index 0000000000..47124d9139 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDao.java @@ -0,0 +1,88 @@ +package com.baeldung.statmentVsPreparedstatment; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class PreparedStatementPersonDao { + + private final Connection connection; + + public PreparedStatementPersonDao(Connection connection) { + this.connection = connection; + } + + public Optional getById(int id) throws SQLException { + String query = "SELECT id, name FROM persons WHERE id = ?"; + + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setInt(1, id); + ResultSet resultSet = preparedStatement.executeQuery(); + + if (resultSet.first()) { + + PersonEntity result = new PersonEntity(resultSet.getInt("id"), + resultSet.getString("name")); + + return Optional.of(result); + } else { + return Optional.empty(); + } + + } + + public void insert(PersonEntity personEntity) throws SQLException { + + String query = "INSERT INTO persons(id, name) VALUES( ?, ?)"; + + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setInt(1, personEntity.getId()); + preparedStatement.setString(2, personEntity.getName()); + preparedStatement.executeUpdate(); + + } + + public void insert(List personEntities) throws SQLException { + String query = "INSERT INTO persons(id, name) VALUES( ?, ?)"; + + PreparedStatement preparedStatement = connection.prepareStatement(query); + for (PersonEntity personEntity : personEntities) { + preparedStatement.setInt(1, personEntity.getId()); + preparedStatement.setString(2, personEntity.getName()); + preparedStatement.addBatch(); + } + preparedStatement.executeBatch(); + + } + + public void update(PersonEntity personEntity) throws SQLException { + String query = "UPDATE persons SET name = ? WHERE id = ?"; + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setString(1, personEntity.getName()); + preparedStatement.setInt(2, personEntity.getId()); + preparedStatement.executeUpdate(); + } + + public void deleteById(int id) throws SQLException { + String query = "DELETE FROM persons WHERE id = ?"; + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setInt(1, id); + preparedStatement.executeUpdate(); + } + + public List getAll() throws SQLException { + String query = "SELECT id, name FROM persons"; + + PreparedStatement preparedStatement = connection.prepareStatement(query); + ResultSet resultSet = preparedStatement.executeQuery(); + List result = new ArrayList<>(); + while (resultSet.next()) { + result.add(new PersonEntity(resultSet.getInt("id"), resultSet.getString("name"))); + } + return result; + } +} diff --git a/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDao.java b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDao.java new file mode 100644 index 0000000000..935ba8efa2 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/main/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDao.java @@ -0,0 +1,75 @@ +package com.baeldung.statmentVsPreparedstatment; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class StatementPersonDao { + + private final Connection connection; + + public StatementPersonDao(Connection connection) { + this.connection = connection; + } + + public Optional getById(int id) throws SQLException { + String query = "SELECT id, name, FROM persons WHERE id = '" + id + "'"; + + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query); + + if (resultSet.first()) { + PersonEntity result = new PersonEntity(resultSet.getInt("id"), + resultSet.getString("name")); + return Optional.of(result); + } else { + return Optional.empty(); + } + } + + public void insert(PersonEntity personEntity) throws SQLException { + String query = "INSERT INTO persons(id, name) VALUES(" + personEntity.getId() + ", '" + + personEntity.getName() + "')"; + + Statement statement = connection.createStatement(); + statement.executeUpdate(query); + } + + public void insert(List personEntities) throws SQLException { + for (PersonEntity personEntity : personEntities) { + insert(personEntity); + } + } + + public void update(PersonEntity personEntity) throws SQLException { + + String query = "UPDATE persons SET name = '" + personEntity.getName() + "' WHERE id = " + + personEntity.getId(); + + Statement statement = connection.createStatement(); + statement.executeUpdate(query); + + } + + public void deleteById(int id) throws SQLException { + String query = "DELETE FROM persons WHERE id = " + id; + Statement statement = connection.createStatement(); + statement.executeUpdate(query); + } + + public List getAll() throws SQLException { + String query = "SELECT id, name, FROM persons"; + + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(query); + List result = new ArrayList<>(); + while (resultSet.next()) { + result.add(new PersonEntity(resultSet.getInt("id"), resultSet.getString("name"))); + } + return result; + } +} diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactoryUnitTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactoryUnitTest.java new file mode 100644 index 0000000000..5d3b151d5d --- /dev/null +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/DatasourceFactoryUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.statmentVsPreparedstatment; + +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class DatasourceFactoryUnitTest { + + @Test + void whenCreateConnectionAndTables_thenConnectionIsOpenAndTableIsCreated() + throws SQLException, ClassNotFoundException { + DatasourceFactory factory = new DatasourceFactory(); + Connection connection = factory.getConnection(); + + assertFalse(connection.isClosed()); + assertTrue(factory.createTables()); + } +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDaoUnitTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDaoUnitTest.java new file mode 100644 index 0000000000..ce79f47802 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/PreparedStatementPersonDaoUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.statmentVsPreparedstatment; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class PreparedStatementPersonDaoUnitTest { + private PreparedStatementPersonDao dao; + + @BeforeEach + void setup() throws SQLException, ClassNotFoundException { + DatasourceFactory datasourceFactory = new DatasourceFactory(); + Connection connection = datasourceFactory.getConnection(); + datasourceFactory.createTables(); + dao = new PreparedStatementPersonDao(connection); + } + + @Test + void whenInsertAPerson_thenItNeverThrowsAnException() { + assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "john"))); + } + + @Test + void whenInsertAPersonWithQuoteInText_thenItNeverThrowsAnException() { + assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "O'Brien"))); + } + + @Test + void whenGetAPersonById_thenItReturnThePersonInDatabase() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + + Optional maybeEmployee = dao.getById(1); + assertTrue(maybeEmployee.isPresent()); + + PersonEntity personEntity = maybeEmployee.get(); + + assertEquals(1, personEntity.getId()); + assertEquals("john", personEntity.getName()); + } + + @Test + void whenInsertAndGetMultiplePersons_thenItNeverThrowsAnException() throws SQLException { + assertDoesNotThrow(() -> dao.insert( + Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skit")))); + + List result = dao.getAll(); + + assertEquals(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skit")), + result); + } + + @Test + void whenUpdateAnExistentPerson_thenItReturnsTheUpdatedPerson() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + dao.update(new PersonEntity(1, "johnny")); + + Optional maybePerson = dao.getById(1); + + assertTrue(maybePerson.isPresent()); + + PersonEntity personEntity = maybePerson.get(); + + assertEquals(1, personEntity.getId()); + assertEquals("johnny", personEntity.getName()); + } + + @Test + void whenDeleteAPersonById_thenItWillBeAbsentInDatabase() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + dao.deleteById(1); + + Optional maybePerson = dao.getById(1); + + assertFalse(maybePerson.isPresent()); + } + + @Test + void whenAHackerUpdateAPerson_thenItUpdatesTheTargetPerson() throws SQLException { + dao.insert(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet"))); + dao.update(new PersonEntity(1, "hacker' --")); + + List result = dao.getAll(); + + assertEquals(Arrays.asList(new PersonEntity(1, "hacker' --"), new PersonEntity(2, "skeet")), + result); + } +} \ No newline at end of file diff --git a/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDaoUnitTest.java b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDaoUnitTest.java new file mode 100644 index 0000000000..b31bdcc296 --- /dev/null +++ b/persistence-modules/core-java-persistence/src/test/java/com/baeldung/statmentVsPreparedstatment/StatementPersonDaoUnitTest.java @@ -0,0 +1,96 @@ +package com.baeldung.statmentVsPreparedstatment; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +class StatementPersonDaoUnitTest { + + private StatementPersonDao dao; + + @BeforeEach + void setup() throws SQLException, ClassNotFoundException { + DatasourceFactory datasourceFactory = new DatasourceFactory(); + Connection connection = datasourceFactory.getConnection(); + datasourceFactory.createTables(); + dao = new StatementPersonDao(connection); + } + + @Test + void whenInsertAPerson_thenItNeverThrowsAnException() { + assertDoesNotThrow(() -> dao.insert(new PersonEntity(1, "john"))); + } + + @Test + void whenInsertAPersonWithQuoteInText_thenItWillThrowAnException() { + assertThrows(SQLException.class, () -> dao.insert(new PersonEntity(1, "O'Brien"))); + } + + @Test + void whenGetAPersonById_thenItReturnThePersonInDatabase() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + + Optional maybeEmployee = dao.getById(1); + + assertTrue(maybeEmployee.isPresent()); + + PersonEntity personEntity = maybeEmployee.get(); + + assertEquals(1, personEntity.getId()); + assertEquals("john", personEntity.getName()); + } + + @Test + void whenInsertAndGetMultiplePersons_thenItNeverThrowsAnException() throws SQLException { + assertDoesNotThrow(() -> dao.insert( + Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")))); + + List result = dao.getAll(); + + assertEquals(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet")), + result); + } + + @Test + void whenUpdateAnExistentPerson_thenItReturnsTheUpdatedPerson() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + dao.update(new PersonEntity(1, "johnny")); + + Optional maybePerson = dao.getById(1); + + assertTrue(maybePerson.isPresent()); + + PersonEntity personEntity = maybePerson.get(); + + assertEquals(1, personEntity.getId()); + assertEquals("johnny", personEntity.getName()); + } + + @Test + void whenDeleteAPersonById_thenItWillBeAbsentInDatabase() throws SQLException { + dao.insert(new PersonEntity(1, "john")); + dao.deleteById(1); + + Optional maybePerson = dao.getById(1); + + assertFalse(maybePerson.isPresent()); + } + + @Test + void whenAHackerUpdateAPerson_thenItAllPersonsAreUpdated() throws SQLException { + dao.insert(Arrays.asList(new PersonEntity(1, "john"), new PersonEntity(2, "skeet"))); + dao.update(new PersonEntity(1, "hacker' --")); + + List result = dao.getAll(); + + assertEquals(Arrays.asList(new PersonEntity(1, "hacker"), new PersonEntity(2, "hacker")), + result); + } +} \ No newline at end of file