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);
+ }
+}