diff --git a/spring-all/pom.xml b/spring-all/pom.xml index fd56aafb33..2d77536fc8 100644 --- a/spring-all/pom.xml +++ b/spring-all/pom.xml @@ -50,7 +50,11 @@ ${mysql-connector-java.version} runtime - + + org.hsqldb + hsqldb + 2.3.2 + diff --git a/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java b/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java new file mode 100644 index 0000000000..4ccecc097b --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java @@ -0,0 +1,23 @@ +package org.baeldung.jdbc; + +import java.sql.SQLException; + +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; + +public class CustomSQLErrorCodeTranslator extends +SQLErrorCodeSQLExceptionTranslator { + + @Override + protected DataAccessException customTranslate(final String task, + final String sql, final SQLException sqlException) { + if (sqlException.getErrorCode() == -104) { + return new DuplicateKeyException( + "Custome Exception translator - Integrity contraint voilation.", + sqlException); + } + return null; + } + +} diff --git a/spring-all/src/main/java/org/baeldung/jdbc/Employee.java b/spring-all/src/main/java/org/baeldung/jdbc/Employee.java new file mode 100644 index 0000000000..8649dfd779 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/jdbc/Employee.java @@ -0,0 +1,44 @@ +package org.baeldung.jdbc; + +public class Employee { + private int id; + + private String firstName; + + private String lastName; + + private String address; + + public int getId() { + return id; + } + + public void setId(final int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(final String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(final String lastName) { + this.lastName = lastName; + } + + public String getAddress() { + return address; + } + + public void setAddress(final String address) { + this.address = address; + } + +} diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java b/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java new file mode 100644 index 0000000000..719bee31fa --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java @@ -0,0 +1,132 @@ +package org.baeldung.jdbc; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; +import org.springframework.jdbc.core.simple.SimpleJdbcInsert; +import org.springframework.stereotype.Repository; + +@Repository +public class EmployeeDAO { + + private JdbcTemplate jdbcTemplate; + + private NamedParameterJdbcTemplate namedParameterJdbcTemplate; + + private SimpleJdbcInsert simpleJdbcInsert; + + @Autowired + public void setDataSource(final DataSource dataSource) { + jdbcTemplate = new JdbcTemplate(dataSource); + final CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = new CustomSQLErrorCodeTranslator(); + jdbcTemplate.setExceptionTranslator(customSQLErrorCodeTranslator); + + namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); + simpleJdbcInsert = new SimpleJdbcInsert(dataSource) + .withTableName("EMPLOYEE"); + + } + + public int getCountOfEmployees() { + return jdbcTemplate.queryForObject("SELECT COUNT(*) FROM EMPLOYEE", + Integer.class); + } + + public List getAllEmployees() { + return jdbcTemplate.query("SELECT * FROM EMPLOYEE", + new EmployeeRowMapper()); + } + + public int addEmplyee(final int id) { + return jdbcTemplate.update("INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", + id, "Bill", "Gates", "USA"); + } + + public int addEmplyeeUsingSimpelJdbcInsert(final Employee emp) { + final Map parameters = new HashMap(); + parameters.put("ID", emp.getId()); + parameters.put("FIRST_NAME", emp.getFirstName()); + parameters.put("LAST_NAME", emp.getLastName()); + parameters.put("ADDRESS", emp.getAddress()); + + return simpleJdbcInsert.execute(parameters); + } + + public Employee getEmployee(final int id) { + final String query = "SELECT * FROM EMPLOYEE WHERE ID = ?"; + return jdbcTemplate.queryForObject(query, new Object[] { id }, + new EmployeeRowMapper()); + } + + public void addEmplyeeUsingExecuteMethod() { + jdbcTemplate + .execute("INSERT INTO EMPLOYEE VALUES (6, 'Bill', 'Gates', 'USA')"); + } + + public String getEmployeeUsingMapSqlParameterSource() { + final SqlParameterSource namedParameters = new MapSqlParameterSource() + .addValue("id", 1); + + return namedParameterJdbcTemplate.queryForObject( + "SELECT FIRST_NAME FROM EMPLOYEE WHERE ID = :id", + namedParameters, String.class); + } + + public int getEmployeeUsingBeanPropertySqlParameterSource() { + final Employee employee = new Employee(); + employee.setFirstName("James"); + + final String SELECT_BY_ID = "SELECT COUNT(*) FROM EMPLOYEE WHERE FIRST_NAME = :firstName"; + + final SqlParameterSource namedParameters = new BeanPropertySqlParameterSource( + employee); + + return namedParameterJdbcTemplate.queryForObject(SELECT_BY_ID, + namedParameters, Integer.class); + } + + public int[] batchUpdateUsingJDBCTemplate(final List employees) { + return jdbcTemplate.batchUpdate( + "INSERT INTO EMPLOYEE VALUES (?, ?, ?, ?)", + new BatchPreparedStatementSetter() { + + @Override + public void setValues(final PreparedStatement ps, + final int i) throws SQLException { + ps.setInt(1, employees.get(i).getId()); + ps.setString(2, employees.get(i).getFirstName()); + ps.setString(3, employees.get(i).getLastName()); + ps.setString(4, employees.get(i).getAddress()); + } + + @Override + public int getBatchSize() { + return 3; + } + }); + } + + public int[] batchUpdateUsingNamedParameterJDBCTemplate( + final List employees) { + final SqlParameterSource[] batch = SqlParameterSourceUtils + .createBatch(employees.toArray()); + final int[] updateCounts = namedParameterJdbcTemplate + .batchUpdate( + "INSERT INTO EMPLOYEE VALUES (:id, :firstName, :lastName, :address)", + batch); + return updateCounts; + } +} diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java b/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java new file mode 100644 index 0000000000..23f38a2959 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java @@ -0,0 +1,22 @@ +package org.baeldung.jdbc; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.springframework.jdbc.core.RowMapper; + +public class EmployeeRowMapper implements RowMapper { + + @Override + public Employee mapRow(final ResultSet rs, final int rowNum) + throws SQLException { + final Employee employee = new Employee(); + + employee.setId(rs.getInt("ID")); + employee.setFirstName(rs.getString("FIRST_NAME")); + employee.setLastName(rs.getString("LAST_NAME")); + employee.setAddress(rs.getString("ADDRESS")); + + return employee; + } +} diff --git a/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java b/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java new file mode 100644 index 0000000000..64e18792a1 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java @@ -0,0 +1,34 @@ +package org.baeldung.jdbc.config; + +import javax.sql.DataSource; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; + +@Configuration +@ComponentScan("org.baeldung.jdbc") +public class SpringJdbcConfig { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL) + .addScript("classpath:jdbc/schema.sql") + .addScript("classpath:jdbc/test-data.sql").build(); + } + + // @Bean + public DataSource mysqlDataSource() { + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName("com.mysql.jdbc.Driver"); + dataSource.setUrl("jdbc:mysql://localhost:3306/springjdbc"); + dataSource.setUsername("guest_user"); + dataSource.setPassword("guest_password"); + + return dataSource; + } + +} \ No newline at end of file diff --git a/spring-all/src/main/resources/jdbc/schema.sql b/spring-all/src/main/resources/jdbc/schema.sql new file mode 100644 index 0000000000..c86d35cdae --- /dev/null +++ b/spring-all/src/main/resources/jdbc/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE EMPLOYEE +( + ID int NOT NULL PRIMARY KEY, + FIRST_NAME varchar(255), + LAST_NAME varchar(255), + ADDRESS varchar(255), +); \ No newline at end of file diff --git a/spring-all/src/main/resources/jdbc/springJdbc-config.xml b/spring-all/src/main/resources/jdbc/springJdbc-config.xml new file mode 100644 index 0000000000..5c792ac3e6 --- /dev/null +++ b/spring-all/src/main/resources/jdbc/springJdbc-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-all/src/main/resources/jdbc/test-data.sql b/spring-all/src/main/resources/jdbc/test-data.sql new file mode 100644 index 0000000000..b9ef8fec25 --- /dev/null +++ b/spring-all/src/main/resources/jdbc/test-data.sql @@ -0,0 +1,7 @@ +INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada'); + +INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA'); + +INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland'); + +INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA'); \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java b/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java new file mode 100644 index 0000000000..29378c9b81 --- /dev/null +++ b/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOTest.java @@ -0,0 +1,144 @@ +package org.baeldung.jdbc; + +import java.util.ArrayList; +import java.util.List; + +import org.baeldung.jdbc.config.SpringJdbcConfig; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { SpringJdbcConfig.class }, loader = AnnotationConfigContextLoader.class) +public class EmployeeDAOTest { + + @Autowired + private EmployeeDAO employeeDao; + + @Test + public void testGetCountOfEmployees() { + Assert.assertEquals(employeeDao.getCountOfEmployees(), 9); + } + + @Test + public void testQueryMethod() { + Assert.assertEquals(employeeDao.getAllEmployees().size(), 4); + } + + @Test + public void testUpdateMethod() { + Assert.assertEquals(employeeDao.addEmplyee(5), 1); + } + + @Test + public void testAddEmployeeUsingSimpelJdbcInsert() { + final Employee emp = new Employee(); + emp.setId(11); + emp.setFirstName("testFirstName"); + emp.setLastName("testLastName"); + emp.setAddress("testAddress"); + + Assert.assertEquals(employeeDao.addEmplyeeUsingSimpelJdbcInsert(emp), 1); + } + + @Test + public void testExecuteMethod() { + employeeDao.addEmplyeeUsingExecuteMethod(); + } + + @Test + public void testMapSqlParameterSource() { + Assert.assertEquals("James", + employeeDao.getEmployeeUsingMapSqlParameterSource()); + } + + @Test + public void testBeanPropertySqlParameterSource() { + Assert.assertEquals(1, + employeeDao.getEmployeeUsingBeanPropertySqlParameterSource()); + } + + @Test + public void testCustomExceptionTranslator() { + employeeDao.addEmplyee(7); + + try { + employeeDao.addEmplyee(7); + } catch (final DuplicateKeyException e) { + System.out.println(e.getMessage()); + Assert.assertTrue(e + .getMessage() + .contains( + "Custome Exception translator - Integrity contraint voilation.")); + } + } + + @Test + public void testBatchUpdateUsingJDBCTemplate() { + final List employees = new ArrayList(); + final Employee emp1 = new Employee(); + emp1.setId(10); + emp1.setFirstName("firstName1"); + emp1.setLastName("lastName1"); + emp1.setAddress("address1"); + + final Employee emp2 = new Employee(); + emp2.setId(20); + emp2.setFirstName("firstName2"); + emp2.setLastName("lastName2"); + emp2.setAddress("address2"); + + final Employee emp3 = new Employee(); + emp3.setId(30); + emp3.setFirstName("firstName3"); + emp3.setLastName("lastName3"); + emp3.setAddress("address3"); + + employees.add(emp1); + employees.add(emp2); + employees.add(emp3); + + employeeDao.batchUpdateUsingJDBCTemplate(employees); + + Assert.assertTrue(employeeDao.getEmployee(10) != null); + Assert.assertTrue(employeeDao.getEmployee(20) != null); + Assert.assertTrue(employeeDao.getEmployee(30) != null); + } + + @Test + public void testBatchUpdateUsingNamedParameterJDBCTemplate() { + final List employees = new ArrayList(); + final Employee emp1 = new Employee(); + emp1.setId(40); + emp1.setFirstName("firstName4"); + emp1.setLastName("lastName4"); + emp1.setAddress("address4"); + + final Employee emp2 = new Employee(); + emp2.setId(50); + emp2.setFirstName("firstName5"); + emp2.setLastName("lastName5"); + emp2.setAddress("address5"); + + final Employee emp3 = new Employee(); + emp3.setId(60); + emp3.setFirstName("firstName6"); + emp3.setLastName("lastName6"); + emp3.setAddress("address6"); + + employees.add(emp1); + employees.add(emp2); + employees.add(emp3); + + employeeDao.batchUpdateUsingNamedParameterJDBCTemplate(employees); + + Assert.assertTrue(employeeDao.getEmployee(40) != null); + Assert.assertTrue(employeeDao.getEmployee(50) != null); + Assert.assertTrue(employeeDao.getEmployee(60) != null); + } +}