From 9c643cd652e52a48efe1213e7a1c4810c070307c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Ju=C3=A1rez?= Date: Mon, 10 Jul 2017 20:04:02 -0500 Subject: [PATCH] BAEL-970 A Guide to Apache Commons DbUtils (#2125) * BAEL-970 A Guide to Apache Commons DbUtils * BAEL-970 A Guide to Apache Commons DbUtils * BAEL-970 A Guide to Apache Commons DbUtils - Added employeeId to Email class - Minor corrections --- libraries/pom.xml | 9 +- .../com/baeldung/commons/dbutils/Email.java | 38 +++++ .../baeldung/commons/dbutils/Employee.java | 67 ++++++++ .../commons/dbutils/EmployeeHandler.java | 45 +++++ .../commons/dbutils/DbUtilsUnitTest.java | 160 ++++++++++++++++++ libraries/src/test/resources/employees.sql | 43 +++++ 6 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 libraries/src/main/java/com/baeldung/commons/dbutils/Email.java create mode 100644 libraries/src/main/java/com/baeldung/commons/dbutils/Employee.java create mode 100644 libraries/src/main/java/com/baeldung/commons/dbutils/EmployeeHandler.java create mode 100644 libraries/src/test/java/com/baeldung/commons/dbutils/DbUtilsUnitTest.java create mode 100644 libraries/src/test/resources/employees.sql diff --git a/libraries/pom.xml b/libraries/pom.xml index 28dd36fceb..dfae8085bb 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -227,6 +227,11 @@ commons-io ${commons.io.version} + + commons-dbutils + commons-dbutils + ${commons.dbutils.version} + org.apache.flink flink-core @@ -369,7 +374,7 @@ com.h2database h2 - 1.4.195 + ${h2.version} pl.pragmatists @@ -530,6 +535,8 @@ 9.4.3.v20170317 4.5.3 2.5 + 1.6 + 1.4.196 9.4.2.v20170220 4.5.3 2.5 diff --git a/libraries/src/main/java/com/baeldung/commons/dbutils/Email.java b/libraries/src/main/java/com/baeldung/commons/dbutils/Email.java new file mode 100644 index 0000000000..c82798d52d --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/dbutils/Email.java @@ -0,0 +1,38 @@ +package com.baeldung.commons.dbutils; + +public class Email { + private Integer id; + private Integer employeeId; + private String address; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Integer getEmployeeId() { + return employeeId; + } + + public void setEmployeeId(Integer employeeId) { + this.employeeId = employeeId; + } + + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + @Override + public String toString() { + return "Email{" + "id=" + id + ", address=" + address + '}'; + } + +} diff --git a/libraries/src/main/java/com/baeldung/commons/dbutils/Employee.java b/libraries/src/main/java/com/baeldung/commons/dbutils/Employee.java new file mode 100644 index 0000000000..e6f34c0201 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/dbutils/Employee.java @@ -0,0 +1,67 @@ +package com.baeldung.commons.dbutils; + +import java.util.Date; +import java.util.List; + +public class Employee { + private Integer id; + private String firstName; + private String lastName; + private Double salary; + private Date hiredDate; + private List emails; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Double getSalary() { + return salary; + } + + public void setSalary(Double salary) { + this.salary = salary; + } + + public Date getHiredDate() { + return hiredDate; + } + + public void setHiredDate(Date hiredDate) { + this.hiredDate = hiredDate; + } + + public List getEmails() { + return emails; + } + + public void setEmails(List emails) { + this.emails = emails; + } + + @Override + public String toString() { + return "Employee{" + "id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", salary=" + salary + ", hiredDate=" + hiredDate + '}'; + } + +} \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/commons/dbutils/EmployeeHandler.java b/libraries/src/main/java/com/baeldung/commons/dbutils/EmployeeHandler.java new file mode 100644 index 0000000000..6f68bafe57 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/commons/dbutils/EmployeeHandler.java @@ -0,0 +1,45 @@ +package com.baeldung.commons.dbutils; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.dbutils.BasicRowProcessor; +import org.apache.commons.dbutils.BeanProcessor; + +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.handlers.BeanListHandler; + +public class EmployeeHandler extends BeanListHandler { + + private Connection connection; + + public EmployeeHandler(Connection con) { + super(Employee.class, new BasicRowProcessor(new BeanProcessor(getColumnsToFieldsMap()))); + this.connection = con; + } + + @Override + public List handle(ResultSet rs) throws SQLException { + List employees = super.handle(rs); + + QueryRunner runner = new QueryRunner(); + BeanListHandler handler = new BeanListHandler<>(Email.class); + String query = "SELECT * FROM email WHERE employeeid = ?"; + for (Employee employee : employees) { + List emails = runner.query(connection, query, handler, employee.getId()); + employee.setEmails(emails); + } + return employees; + } + + public static Map getColumnsToFieldsMap() { + Map columnsToFieldsMap = new HashMap<>(); + columnsToFieldsMap.put("FIRST_NAME", "firstName"); + columnsToFieldsMap.put("LAST_NAME", "lastName"); + columnsToFieldsMap.put("HIRED_DATE", "hiredDate"); + return columnsToFieldsMap; + } +} diff --git a/libraries/src/test/java/com/baeldung/commons/dbutils/DbUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/dbutils/DbUtilsUnitTest.java new file mode 100644 index 0000000000..8eb2fd1350 --- /dev/null +++ b/libraries/src/test/java/com/baeldung/commons/dbutils/DbUtilsUnitTest.java @@ -0,0 +1,160 @@ +package com.baeldung.commons.dbutils; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.apache.commons.dbutils.AsyncQueryRunner; +import org.apache.commons.dbutils.DbUtils; +import org.apache.commons.dbutils.QueryRunner; +import org.apache.commons.dbutils.handlers.BeanListHandler; +import org.apache.commons.dbutils.handlers.MapListHandler; +import org.apache.commons.dbutils.handlers.ScalarHandler; +import org.junit.After; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +public class DbUtilsUnitTest { + + private Connection connection; + + @Before + public void setupDB() throws Exception { + Class.forName("org.h2.Driver"); + String db = "jdbc:h2:mem:;INIT=runscript from 'classpath:/employees.sql'"; + connection = DriverManager.getConnection(db); + } + + @After + public void closeBD() { + DbUtils.closeQuietly(connection); + } + + @Test + public void givenResultHandler_whenExecutingQuery_thenExpectedList() throws SQLException { + MapListHandler beanListHandler = new MapListHandler(); + + QueryRunner runner = new QueryRunner(); + List> list = runner.query(connection, "SELECT * FROM employee", beanListHandler); + + assertEquals(list.size(), 5); + assertEquals(list.get(0) + .get("firstname"), "John"); + assertEquals(list.get(4) + .get("firstname"), "Christian"); + } + + @Test + public void givenResultHandler_whenExecutingQuery_thenEmployeeList() throws SQLException { + BeanListHandler beanListHandler = new BeanListHandler<>(Employee.class); + + QueryRunner runner = new QueryRunner(); + List employeeList = runner.query(connection, "SELECT * FROM employee", beanListHandler); + + assertEquals(employeeList.size(), 5); + assertEquals(employeeList.get(0) + .getFirstName(), "John"); + assertEquals(employeeList.get(4) + .getFirstName(), "Christian"); + } + + @Test + public void givenResultHandler_whenExecutingQuery_thenExpectedScalar() throws SQLException { + ScalarHandler scalarHandler = new ScalarHandler<>(); + + QueryRunner runner = new QueryRunner(); + String query = "SELECT COUNT(*) FROM employee"; + long count = runner.query(connection, query, scalarHandler); + + assertEquals(count, 5); + } + + @Test + public void givenResultHandler_whenExecutingQuery_thenEmailsSetted() throws SQLException { + EmployeeHandler employeeHandler = new EmployeeHandler(connection); + + QueryRunner runner = new QueryRunner(); + List employees = runner.query(connection, "SELECT * FROM employee", employeeHandler); + + assertEquals(employees.get(0) + .getEmails() + .size(), 2); + assertEquals(employees.get(2) + .getEmails() + .size(), 3); + assertNotNull(employees.get(0).getEmails().get(0).getEmployeeId()); + } + + @Test + public void givenResultHandler_whenExecutingQuery_thenAllPropertiesSetted() throws SQLException { + EmployeeHandler employeeHandler = new EmployeeHandler(connection); + + QueryRunner runner = new QueryRunner(); + String query = "SELECT * FROM employee_legacy"; + List employees = runner.query(connection, query, employeeHandler); + + assertEquals((int) employees.get(0).getId(), 1); + assertEquals(employees.get(0).getFirstName(), "John"); + } + + @Test + public void whenInserting_thenInserted() throws SQLException { + QueryRunner runner = new QueryRunner(); + String insertSQL = "INSERT INTO employee (firstname,lastname,salary, hireddate) VALUES (?, ?, ?, ?)"; + + int numRowsInserted = runner.update(connection, insertSQL, "Leia", "Kane", 60000.60, new Date()); + + assertEquals(numRowsInserted, 1); + } + + @Test + public void givenHandler_whenInserting_thenExpectedId() throws SQLException { + ScalarHandler scalarHandler = new ScalarHandler<>(); + + QueryRunner runner = new QueryRunner(); + String insertSQL = "INSERT INTO employee (firstname,lastname,salary, hireddate) VALUES (?, ?, ?, ?)"; + + int newId = runner.insert(connection, insertSQL, scalarHandler, "Jenny", "Medici", 60000.60, new Date()); + + assertEquals(newId, 6); + } + + @Test + public void givenSalary_whenUpdating_thenUpdated() throws SQLException { + double salary = 35000; + + QueryRunner runner = new QueryRunner(); + String updateSQL = "UPDATE employee SET salary = salary * 1.1 WHERE salary <= ?"; + int numRowsUpdated = runner.update(connection, updateSQL, salary); + + assertEquals(numRowsUpdated, 3); + } + + @Test + public void whenDeletingRecord_thenDeleted() throws SQLException { + QueryRunner runner = new QueryRunner(); + String deleteSQL = "DELETE FROM employee WHERE id = ?"; + int numRowsDeleted = runner.update(connection, deleteSQL, 3); + + assertEquals(numRowsDeleted, 1); + } + + @Test + public void givenAsyncRunner_whenExecutingQuery_thenExpectedList() throws Exception { + AsyncQueryRunner runner = new AsyncQueryRunner(Executors.newCachedThreadPool()); + + EmployeeHandler employeeHandler = new EmployeeHandler(connection); + String query = "SELECT * FROM employee"; + Future> future = runner.query(connection, query, employeeHandler); + List employeeList = future.get(10, TimeUnit.SECONDS); + + assertEquals(employeeList.size(), 5); + } + +} diff --git a/libraries/src/test/resources/employees.sql b/libraries/src/test/resources/employees.sql new file mode 100644 index 0000000000..c6109724cf --- /dev/null +++ b/libraries/src/test/resources/employees.sql @@ -0,0 +1,43 @@ +CREATE TABLE employee( + id int NOT NULL PRIMARY KEY auto_increment, + firstname varchar(255), + lastname varchar(255), + salary double, + hireddate date +); + +CREATE TABLE email( + id int NOT NULL PRIMARY KEY auto_increment, + employeeid int, + address varchar(255) +); + +CREATE TABLE employee_legacy( + id int NOT NULL PRIMARY KEY auto_increment, + first_name varchar(255), + last_name varchar(255), + salary double, + hired_date date +); + + +INSERT INTO employee (firstname,lastname,salary,hireddate) VALUES ('John', 'Doe', 10000.10, to_date('01-01-2001','dd-mm-yyyy')); +INSERT INTO employee (firstname,lastname,salary,hireddate) VALUES ('Kevin', 'Smith', 20000.20, to_date('02-02-2002','dd-mm-yyyy')); +INSERT INTO employee (firstname,lastname,salary,hireddate) VALUES ('Kim', 'Smith', 30000.30, to_date('03-03-2003','dd-mm-yyyy')); +INSERT INTO employee (firstname,lastname,salary,hireddate) VALUES ('Stephen', 'Torvalds', 40000.40, to_date('04-04-2004','dd-mm-yyyy')); +INSERT INTO employee (firstname,lastname,salary,hireddate) VALUES ('Christian', 'Reynolds', 50000.50, to_date('05-05-2005','dd-mm-yyyy')); + +INSERT INTO employee_legacy (first_name,last_name,salary,hired_date) VALUES ('John', 'Doe', 10000.10, to_date('01-01-2001','dd-mm-yyyy')); +INSERT INTO employee_legacy (first_name,last_name,salary,hired_date) VALUES ('Kevin', 'Smith', 20000.20, to_date('02-02-2002','dd-mm-yyyy')); +INSERT INTO employee_legacy (first_name,last_name,salary,hired_date) VALUES ('Kim', 'Smith', 30000.30, to_date('03-03-2003','dd-mm-yyyy')); +INSERT INTO employee_legacy (first_name,last_name,salary,hired_date) VALUES ('Stephen', 'Torvalds', 40000.40, to_date('04-04-2004','dd-mm-yyyy')); +INSERT INTO employee_legacy (first_name,last_name,salary,hired_date) VALUES ('Christian', 'Reynolds', 50000.50, to_date('05-05-2005','dd-mm-yyyy')); + +INSERT INTO email (employeeid,address) VALUES (1, 'john@baeldung.com'); +INSERT INTO email (employeeid,address) VALUES (1, 'john@gmail.com'); +INSERT INTO email (employeeid,address) VALUES (2, 'kevin@baeldung.com'); +INSERT INTO email (employeeid,address) VALUES (3, 'kim@baeldung.com'); +INSERT INTO email (employeeid,address) VALUES (3, 'kim@gmail.com'); +INSERT INTO email (employeeid,address) VALUES (3, 'kim@outlook.com'); +INSERT INTO email (employeeid,address) VALUES (4, 'stephen@baeldung.com'); +INSERT INTO email (employeeid,address) VALUES (5, 'christian@gmail.com');