Monday, July 13, 2020

Spring JdbcTemplate Select Query Example

In the post Spring JdbcTemplate Insert, Update And Delete Example I have already discussed how JdbcTemplate can be used for inserting and updating data in the DB. I left behind the part to read from Database using Select query. Purpose for doing that is to discuss in detail the callback part of the JdbcTemplate. This post shows how to use Select query using JdbcTemplate in Spring framework and also talks about the callback methods in detail which shows how you can do resultset to model mapping using RowMapper implementation.

In the post Data access in Spring framework it has been discussed in detail how Spring framework provides templates to manage the fixed part and uses call back to handle the variable part. Fetching data from DB using select query has, as usual, the fixed part like getting connection, cleaning up, handling exception but at the same time Spring framework does need help to map the fetched data to the model. That’s where callback comes into picture.

Technologies used

  • Spring 5.0.4
  • Apache DBCP2
  • MYSQL 5.1.39
  • Java 8
  • Apache Maven 3.3.3

In this Spring JdbcTemplate select query example Apache DBCP is used for providing pooled datasource and MYSQL is used as the back end.


Maven dependencies

If you are using maven then you can provide dependencies in your pom.xml.

With all the dependencies your pom.xml should look something like this -

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.netjs.prog</groupId>
  <artifactId>maven-spring</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>maven-spring</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>5.0.4.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>javax.inject</groupId>
      <artifactId>javax.inject</artifactId>
      <version>1</version>
    </dependency>
    
    <!-- Spring JDBC Support -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <!-- MySQL Driver -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.39</version>
    </dependency>
    
    <!--  Apache DBCP connection pool -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.1</version>
    </dependency>
  </dependencies>
</project>

Alternatively you can download the jars and add them to the class path.

Database table for example

For this example I have created a table called employee with the columns id, name and age in the MYSQL DB. Column id is configured as auto increment checked so no need to pass id from your query as DB will provide value for it.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

Configuring datasource dependency

First thing is to set up DataSource as a bean. I have used properties file to configure datasource where all the properties are there in the db.properties file.

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value = "${db.driverClassName}" />
    <property name="url" value = "${db.url}" />
    <property name="username" value = "${db.username}" />
    <property name="password" value = "${db.password}" />
    <property name="initialSize" value = "${pool.initialSize}" />
</bean>

Where as db.properties file which is under the config folder has all the properties.

db.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/netjs
db.username=
db.password=
pool.initialSize=5

Description of the properties is as-

driver class name is the JDBC driver for the DB used. Since MYSQL is used here so the jdbc driver for the same (com.mysql.jdbc.Driver) is provided.

Url – You need to provide url to access your DB server. I have created a schema called netjs and DB is running on the same system so url is jdbc:mysql://localhost:3306/netjs.

Username and password for the DB.

IntialSize is the initial size of the connection pool. It is given as 5 so initially 5 connections will be created and stored in the pool.

To use properties file you need to put following configuration in your XML.

<context:property-placeholder location="classpath:config/db.properties" />

Spring JDBCTemplate configuration

DataSource bean has to be provided as a reference in JdbcTemplate.

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <property name="dataSource" ref="dataSource"></property>  
</bean>

Java Classes

Since Spring always promotes to use interfaces and there is also a JEE design pattern for database layer called DAO which also says the same thing - Separate low level data access code from the business layers.

So we have a EmployeeDAO interface with find methods and its implementing class EmployeeDAOImpl. There is also a model class Employee with all the getters/setters.

Employee.java class

public class Employee {
 private int empId;
 private String empName;
 private int age;
 
 public int getEmpId() {
  return empId;
 }
 public void setEmpId(int empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
}

EmployeeDAO interface

import org.netjs.model.Employee;

public interface EmployeeDAO {
  public List<Employee> findAllEmployees();
  
  public Employee findEmployee(int empId);
}

EmployeeDAOImpl class

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAOImpl implements EmployeeDAO {
  @Autowired
  private JdbcTemplate jdbcTemplate; 
  
  final String SELECT_BY_ID_QUERY = "SELECT id, name, age from EMPLOYEE where id = ?";
  final String SELECT_ALL_QUERY = "SELECT id, name, age from EMPLOYEE";
  
  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
    this.jdbcTemplate = jdbcTemplate;  
  }
    
  public Employee findEmployee(int empId) {
    return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, new EmployeeMapper(), 
    empId);
  }

  public List<Employee> findAllEmployees() {
    return this.jdbcTemplate.query(SELECT_ALL_QUERY, new EmployeeMapper());
  }

  private static final class EmployeeMapper implements RowMapper<Employee> {
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
      Employee emp = new Employee();
      emp.setEmpId(rs.getInt("id"));
      emp.setEmpName(rs.getString("name"));
      emp.setAge(rs.getInt("age"));
      return emp;
    }
  }  
}

Notice how you are not writing any code for getting or closing connection, exception handling. All that fixed part is managed by the JdbcTemplate class. Its the JdbcTemplate which is getting the connection using the DataSource provided to it, creating and executing the statement and closing the connection.

If there is any SQLException thrown that is also caught by JdbcTemplate and translated to one of the DataAccessException and rethrown.

Spring RowMapper

Main thing to demonstrate in this Spring JdbcTemplate select query example is how callback works. Here template callbacks are used to query the DB and then map the returned result set to the model (Employee) object(s).

If you have noticed in findEmployee(int empId) method queryForObject method of JdbcTemplate is used which takes 3 parameters-

  • SQL query String
  • RowMapper object that maps a single result row to a Java object via a RowMapper
  • varargs to bind parameters to the query

Whereas in findAllEmployees() method query method is used which takes only two parameters –

  • SQL query String
  • RowMapper object

as there are no parameters to be passed to the SQL so varargs are not needed in this case.

Main thing here is RowMapper object which in this example is the object of class EmployeeMapper implementing the RowMapper interface.
RowMapper interface has a single method mapRow which takes two arguments -

  1. ResultSet - A table of data representing a database result set
  2. int - the number of the current row
and this method returns the result object for the current row.

For every row in the result set, JdbcTemplate calls the mapRow() method of the RowMapper interface implementing class. Arguments passed are ResultSet and an integer which is the number of the current row in the result set. Using that row number cursor is moved to the given row in the result set.

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="org.netjs.daoimpl" />
    <!--  For reading properties files --> 
    <context:property-placeholder location="classpath:config/db.properties" />
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name="dataSource" ref="dataSource"></property>  
    </bean>  
    <!-- <bean id="employeeDAO" class="org.netjs.daoimpl.EmployeeDAOImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>  
    </bean> -->
    
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value = "${db.driverClassName}" />
        <property name="url" value = "${db.url}" />
        <property name="username" value = "${db.username}" />
        <property name="password" value = "${db.password}" />
        <property name="initialSize" value = "${pool.initialSize}" />
    </bean>

</beans>

If you are not using component scanning, then you can uncomment the bean definition for the EmployeeDAO.

Test class

You can use the following code in order to test the code -

import java.util.List;
import org.netjs.dao.EmployeeDAO;
import org.netjs.model.Employee;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
  public static void main(String[] args) {
    
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
     ("appcontext.xml");
    EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAOImpl");  
    
    // Uncomment this to find employee by ID
    /*Employee emp = dao.findEmployee(5);
    System.out.println("Name - "+ emp.getEmpName() + " Age - " + emp.getAge());*/
    
    List<Employee> empList = dao.findAllEmployees();
    System.out.println("Name - "+ empList.get(1).getEmpName() + " Age - " 
      + empList.get(1).getAge());
  }
}

RowMapper implementation as Lambda Expression

RowMapper interface has only single method mapRow which means it is a functional interface. Starting Java 8 it can be implemented as a lambda expression. Since same implementation is used by two methods findEmployee() and findAllEmployees() so it is better to implement it as a lambda block rather than as an inline lambda.

In that case findEmployee() and findAllEmployees() methods will change like this -

public Employee findEmployee(int EmpId) {
  return this.jdbcTemplate.queryForObject(SELECT_BY_ID_QUERY, getMap(), EmpId);
}

public List<Employee> findAllEmployees() {
  return this.jdbcTemplate.query(SELECT_ALL_QUERY, getMap());
}
    
private RowMapper<Employee> getMap(){
  // Lambda block
  RowMapper<Employee> empMap = (rs, rowNum) -> {
      Employee emp = new Employee();
      emp.setEmpId(rs.getInt("id"));
      emp.setEmpName(rs.getString("name"));
      emp.setAge(rs.getInt("age"));
      return emp;
  };
  return empMap;
}

Here it can be seen that lambda block is implemented inside method getMap(). Here lambda is assigned to a functional interface (RowMapper in this case) variable. It has two arguments rs and rowNum, since it is implementing mapRow() method of the RowMapper class so compiler will infer that rs and rowNum are of type ResultSet and int respectively.

That's all for this topic Spring JdbcTemplate Select Query Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Configuring DataSource in Spring Framework
  2. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  3. Spring NamedParameterJdbcTemplate Select Query Example
  4. How to Inject Prototype Scoped Bean into a Singleton Bean in Spring
  5. Spring Profiles With Examples

You may also like-

  1. Spring Component Scan Example
  2. Excluding Bean From Autowiring in Spring
  3. @Resource Annotation in Spring Autowiring
  4. interface default methods in Java 8
  5. Is String Thread Safe in Java
  6. Difference Between Thread And Process in Java
  7. AtomicInteger in Java With Examples
  8. Java BlockingDeque With Examples

Saturday, July 11, 2020

Data Access in Spring Framework

This Spring data access tutorial provides basics about the DB access through Spring framework like how Spring abstracts the data access, how you can use templates for data access, Spring’s data access exception handling.

If you have to describe how data access is handled by Spring Framework using 2 keywords then those 2 words will be-

  • Abstraction
  • Agnostic

Now JDBC or any ORM framework do provide abstraction of its own and you use JDBC or ORM as an abstract layer to interact with DB then what abstraction does spring provide?

Again two keywords are-

  • Template
  • Exception Handling

Before delving any further into those keywords let’s talk about the “agnostic” feature too (which will cover the Exception handling point too!). It is said that data access exception handling in Spring framework is platform agnostic. What does that mean?

Spring’s data access exception handling is platform agnostic

If you have used JDBC you must be knowing that it forces you to catch SQLException. SQLException is an exception that provides information on a database access error or other errors some of the scenarios when SQLException can be thrown are-

  • The application is not able to connect to the DB.
  • SQL Query which has to be executed is not correct syntactically.

But the question here is by catching SQLException you can’t do much anyway. Also the SQLException hierarchy is not very rich. Though it does provide a String describing the error and an integer error code that is specific to each vendor which is helpful in knowing about the error.

Coming to Spring framework it provides data access mechanism for getting data through JDBC, various ORM frameworks like Hibernate, Ibatis. Now think of a situation where Spring provides the layer over the JDBC or any ORM framework but doesn’t provide any mechanism to handle exceptions thrown by them. In that case your code will become a hotchpotch of Spring templates and then exception handling by JDBC, Hibernate, Ibatis or any other way of data access. That’s where Spring’s platform agnostic exception handling comes to the rescue.

For JDBC org.springframework.jdbc.support package provides SQLException translation functionality and some utility classes. Exceptions thrown during JDBC processing are translated to exceptions defined in the org.springframework.dao package. This means that code using the Spring JDBC abstraction layer does not need to implement JDBC or RDBMS-specific error handling.

All translated exceptions are unchecked exceptions, which gives you the option of catching the exceptions from which you can recover while allowing other exceptions to be propagated to the caller.

Same way implementations of PersistenceExceptionTranslator interface in Spring provides exception translation for data access technologies that throw runtime exceptions, such as JPA, TopLink, JDO and Hibernate.

Using these translator classes Spring translates the platform specific exception to the Spring specific exception under the hood, so you are abstracted from how it is done.

Some of the advantages of the exception handling mechanism followed by Spring are-

  1. Non-intrusive– Since data access exceptions thrown by Spring are not checked exceptions so user is not forced to handle it or declare it. That way you are not making your application tightly coupled with the Spring APIs.
  2. Catch Late- In case of checked exceptions, it is enforced by Java compiler to either catch the exception or declare it in throws clause. So generally developer tends to catch it and do nothing except printing stacktrace or put a logger in order to avoid the compiler error. But that way we are not providing the true information of what exactly happened. It is better to catch exception only when it can be handled appropriately. Since Spring's data access exceptions are unchecked exceptions theses exceptions can be thrown up the call hierarchy, without the botheration of declaring with throws clause or rethrowing them, and the best place in the hierarchy can handle it more effectively.

Spring data access Exception Hierarchy

Spring’s exception hierarchy is quite rich and the main thing is that it can be used with any persistence solution. Whatever persistence solution you are using, if exception is thrown Spring framework will translate it and throw a consistent set of exceptions.

Parent class in Spring's exception hierarchy is DataAccessException and important point about is that it is an unchecked exception. So, you are not forced to catch Spring's data access exceptions, though you can catch them if you want. In fact the convention is that you should not handle any exceptions in the DAO layer, instead throw it to the front-end and handle it.

Some of the sub classes of the DataAccessException class are– BadSqlGrammarException, DuplicateKeyException, EmptyResultDataAccessException, CannotGetJdbcConnectionException, QueryTimeoutException. There are many more if you want to go through the whole list please refer Spring reference doc.

In order to take advantage of Spring’s data-access exceptions, you need to use one of the data access templates provided by Spring framework. That brings us to the point about templates.

Using Templates for Data Access in Spring

Spring provides many templates for data access (For JDBC, for Hibernate, for MongoDB and many more). If you have idea about template design pattern you can get an idea what these templates are doing.

You generally use Template design pattern if you have to design the functionality where some implementation is common among the classes and some implementation differs. So in template design pattern -

  • There is a base class with common implementations.
  • Methods that require individual implementation are mere place holder in base class.
  • Sub classes can provide implementation for those place holder methods.

So, base class provides the template of the implementation and fill what it can (common implementation) and delegates the other parts to the implementing classes.

Same process is used by the Spring data access. Whatever persistence mechanism is used there are some common steps like getting the DB connection, handling exception if thrown and cleaning up the resources (closing the connection) once done. These can be termed as fixed part.

But how and what data is accessed, what data is updated is different for different application. That can be termed as variable part.

Template classes in Spring framework provide implementation for the fixed part and uses a callback approach to handle variable part which is your custom data access code, benefit of template class is that it frees application code from having to do the boilerplate tasks like getting DB connection, handling exceptions, closing connection and results in code that is intention driven. That way the code that is written focuses solely on what the developer wants to do.

As example- JdbcTemplate class is the central class in the JDBC core package. It handles the creation and release of resources, which helps you avoid common errors such as forgetting to close the connection.
It performs the basic tasks of the core JDBC workflow such as statement creation and execution, leaving application code to provide SQL and extract results. The JdbcTemplate class executes SQL queries, update statements and stored procedure calls, performs iteration over ResultSets and extraction of returned parameter values. It also catches JDBC exceptions and translates them to the generic, more informative, exception hierarchy defined in the org.springframework.dao package.

When you use the JdbcTemplate for your code, you only need to implement callback interfaces, giving them a clearly defined contract. The PreparedStatementCreator callback interface creates a prepared statement given a Connection provided by this class, providing SQL and any necessary parameters. The same is true for the CallableStatementCreator interface, which creates callable statements. The RowCallbackHandler interface extracts values from each row of a ResultSet.

Some of the templates provided by Spring framework-

  • jdbc.core.JdbcTemplate– For JDBC connections.
  • jdbc.core.namedparam.NamedParameterJdbcTemplate- For JDBC connections with named parameters.
  • orm.hibernate3.HibernateTemplate– For Hibernate 3.x sessions.
  • orm.hibernate4.HibernateTemplate- For Hibernate 4.x sessions.
  • org.springframework.orm.hibernate5.HibernateTemplate- For Hibernate 5.x sessions.

In order to manage the fixed part like getting connection, releasing resources Spring template needs a reference to a DataSource. Refer Configuring DataSource in Spring Framework to see different ways to configure data source in Spring.

That's all for this topic Data Access in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  2. Spring JdbcTemplate With ResultSetExtractor Example
  3. Spring Batch Processing Using JDBCTemplate batchUpdate() Method
  4. How to Inject Prototype Scoped Bean in Singleton Bean
  5. How to Read Properties File in Spring Framework

You may also like-

  1. Dependency Injection in Spring Framework
  2. Autowiring using XML configuration in Spring
  3. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  4. Creating a Maven project in Eclipse
  5. Lambda expressions in Java 8
  6. LinkedHashMap in Java With Examples
  7. Difference Between ReentrantLock and Synchronized in Java
  8. Switch Case Statement in Java With Examples

Friday, July 10, 2020

Spring Batch Processing Using JDBCTemplate batchUpdate() Method

If you have a large number of similar queries it is better to process them in a batch. Processing them as a batch provides better performance as you send a group of queries in a single network communication rather than sending individual queries one by one. Spring JdbcTemplate class supports batch processing using batchUpdate() method.

Spring JdbcTemplate batch processing

For batch processing you can use batchUpdate() method of the Spring JdbcTemplate. As the first parameter of the batchUpdate() you will pass the query that has to be used for batch processing and as second parameter you need to pass the interface BatchPreparedStatementSetter. This interface has two methods which you need to implement.

  • setValues()- This method is used to set the values for the parameters of the prepared statement.
  • getBatchSize()- This method is used to provide the size of the current batch.

Spring JdbcTemplate batch processing using batchUpdate() example

Let’s see an example of inserting rows in a DB table as a batch using Spring JdbcTemplate batch processing.

Technologies used

  • Spring 5.0.4
  • Apache DBCP2
  • MYSQL 5.1.39
  • Java 10
  • Apache Maven 3.3.3

In this batch processing tutorial Apache DBCP is used which provides pooled datasource and MYSQL is used as the back end.

Maven dependencies

If you are using Apache Maven then you can provide dependencies in your pom.xml. Alternatively you can download the jars and add them to the class path.

With all the dependencies your pom.xml should look something like this -

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.netjs</groupId>
  <artifactId>SpringExp</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringExp</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>5.0.4.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
        <!-- Spring JDBC Support -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    
   <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.39</version>
    </dependency>
    
    <!--  Apache DBCP connection pool -->
    <dependency>
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-dbcp2</artifactId>
       <version>2.1</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Database table

For this example I have created a table called employee with the columns id, name and age in the MYSQL DB. Column id is configured as auto increment checked so no need to pass id from your query as DB will generate value for it.

CREATE TABLE `employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

DataSource Configuration

DataBase properties are retrieved from a properties file rather than hardcoding in the configuration file. Properties file is stored at the location config/db.properties.

db.properties

db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/netjs
db.username=
db.password=
pool.initialSize=5

Java Classes

Java classes needed for Spring batch processing example are as follows-

  1. Employee Bean class (Employee.java)
  2. DAO interface (EmployeeDAO.java)
  3. DAO interface implementation class (EmployeeDAOImpl.java)

Employee.java

public class Employee {
 private int empId;
 private String empName;
 private int age;
 public Employee(String empName, int age){
  this.empName = empName;
  this.age = age;
 }
 public int getEmpId() {
  return empId;
 }
 public void setEmpId(int empId) {
  this.empId = empId;
 }
 public String getEmpName() {
  return empName;
 }
 public void setEmpName(String empName) {
  this.empName = empName;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
}

EmployeeDAO.java

public interface EmployeeDAO {
  public int[] batchInsert(final List<Employee> employees);
}

EmployeeDAOImpl.java

@Repository
public class EmployeeDAOImpl implements EmployeeDAO{
  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Override
  public int[] batchInsert(final List<Employee> employees) {
    final String INSERT_EMP_QUERY = "insert into employee (name, age) values (?, ?)";
    return this.jdbcTemplate.batchUpdate(INSERT_EMP_QUERY,
      new BatchPreparedStatementSetter() {
      
      @Override
      public void setValues(PreparedStatement ps, int i) throws SQLException {
        // emp id is auto generated so not provided
        ps.setString(1, employees.get(i).getEmpName());
        ps.setInt(2, employees.get(i).getAge());        
      }
                    
      @Override
      public int getBatchSize() {
          return employees.size();
      }
    });            
  } 
}
Logic for Spring batch processing is in the bacthInsert() method, where jdbcTemplate.batchUpdate method is called with the query and instance of BatchPreparedStatementSetter. Note that in the class Spring autowiring is used to inject dependencies. Also class is annotated with @Repository annotation so that the class can be automatically discovered using component scanning in Spring.

batchUpdate() method retruns an array of the number of rows affected by each statement.

XML Configuration (appContext.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:component-scan base-package="org.netjs.DAOImpl" />
    <!--  For reading properties files --> 
    <context:property-placeholder location="classpath:config/db.properties" />
    <!-- Data Source configuration --> 
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value = "${db.driverClassName}" />
        <property name="url" value = "${db.url}" />
        <property name="username" value = "${db.username}" />
        <property name="password" value = "${db.password}" />
        <property name="initialSize" value = "${pool.initialSize}" />
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
        <property name="dataSource" ref="dataSource"></property>  
    </bean> 
</beans>

Test class

You can use the following code in order to test the batch insertion of rows in DB table.

public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
             ("appcontext.xml");
    EmployeeDAO empDAO = context.getBean("employeeDAOImpl", EmployeeDAOImpl.class);
    List<Employee> empList = createEmpList();
    int[] rows = empDAO.batchInsert(empList);
    System.out.println("Number of rows inserted- " + rows.length);
  }
    
  private static List<Employee> createEmpList(){
    Employee emp1 = new Employee("Ben", 25);
    Employee emp2 = new Employee("Virat", 29);
    Employee emp3 = new Employee("Joe", 26);
    List<Employee> empList= new ArrayList<Employee>();
    empList.add(emp1);
    empList.add(emp2);
    empList.add(emp3);
    return empList;
  }
}

Output

Aug 06, 2018 12:25:45 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6fc6f14e: startup date [Mon Aug 06 12:25:44 IST 2018]; root of context hierarchy
Aug 06, 2018 12:25:45 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Number of rows inserted- 3

Batch operation with multiple batches

You may want to break your batches into several small batches. Though it can be done by making several calls to batchUpdate() method but there is an overloaded variant of batchUpdate() method where you can pass the number of updates to make for each batch and an interface ParameterizedPreparedStatementSetter to set the values for the parameters of the prepared statement. The framework loops over the provided values and breaks the update calls into batches of the size specified.

The batch update methods for this call returns an array of int arrays containing an array entry for each batch with an array of the number of affected rows for each update. The top level array’s length indicates the number of batches executed and the second level array’s length indicates the number of updates in that batch.

Here is an example which shows a batch update using a batch size of 3:

Spring JdbcTemplate batchUpdate example with multiple batches

EmployeeDAO.java

public interface EmployeeDAO {
  public int[][] batchInsert(final List<Employee> employees);
}

EmployeeDAOImpl.java

@Repository
public class EmployeeDAOImpl implements EmployeeDAO{
  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Override
  public int[][] batchInsert(final List<Employee> employees) {
    final String INSERT_EMP_QUERY = "insert into employee (name, age) values (?, ?)";
    return this.jdbcTemplate.batchUpdate(INSERT_EMP_QUERY, employees, 3,
     new ParameterizedPreparedStatementSetter<Employee>() {
      @Override
      public void setValues(PreparedStatement ps, Employee emp) throws SQLException {
          ps.setString(1, emp.getEmpName());
          ps.setInt(2, emp.getAge());                    
      }
    });
  } 
}
XML file is same as above. You can run the Spring batch processing example using the following code.
public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
             ("appcontext.xml");
    EmployeeDAO empDAO = context.getBean("employeeDAOImpl", EmployeeDAOImpl.class);
    List<Employee> empList = createEmpList();
    int[][] rows = empDAO.batchInsert(empList);    
    for(int i = 0; i < rows.length; i++) {        
      System.out.println("Number of rows inserted- " + rows[i].length);    
    }        
  }
    
  private static List<Employee> createEmpList(){
    Employee emp1 = new Employee("Mike", 32);
    Employee emp2 = new Employee("Rahul", 27);
    Employee emp3 = new Employee("Smith", 28);
    Employee emp4 = new Employee("Steve", 45);
    Employee emp5 = new Employee("Rajesh", 21);
    List<Employee> empList= new ArrayList<Employee>();
    empList.add(emp1);
    empList.add(emp2);
    empList.add(emp3);
    empList.add(emp4);
    empList.add(emp5);
    return empList;
  }
}

Output

Aug 07, 2018 10:21:36 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6fc6f14e: startup date [Tue Aug 07 10:21:36 IST 2018]; root of context hierarchy
Aug 07, 2018 10:21:36 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [appcontext.xml]
Number of rows inserted- 3
Number of rows inserted- 2

That's all for this topic Spring Batch Processing Using JDBCTemplate batchUpdate() Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Batch Processing With List of Objects in batchUpdate() Method
  2. Spring JdbcTemplate With ResultSetExtractor Example
  3. Spring Transaction Management Example - @Transactional Annotation and JDBC
  4. Spring NamedParameterJdbcTemplate Insert, Update And Delete Example
  5. Batch Processing in Java JDBC - Insert, Update Queries as a Batch

You may also like-

  1. Benefits, Disadvantages And Limitations of Autowiring in Spring
  2. Injecting Inner Bean in Spring
  3. Bean Scopes in Spring With Examples
  4. Circular Dependency in Spring Framework
  5. Transient Keyword in Java With Examples
  6. Functional Interfaces in Java
  7. Try-With-Resources in Java With Examples
  8. BigDecimal in Java With Examples

Monday, July 6, 2020

BeanPostProcessor in Spring Framework

If you want to implement some additional custom logic after the Spring container finishes instantiating, configuring, and initializing a bean, you can plug in one or more BeanPostProcessor implementations.

The BeanPostProcessor interface in the Spring framework defines callback methods that you can implement to perform custom logic on the bean instances. Note that BeanPostProcessors operate on bean instances; the Spring IoC container instantiates a bean instance and then BeanPostProcessors do their work on those created instances. These instances are passed as argument to the callback methods. BeanPostProcessor callback methods are called on each bean created by the Springcontainer.

A bean post-processor typically checks for callback interfaces or may wrap a bean with a proxy.

BeanPostProcessor callback methods

The org.springframework.beans.factory.config.BeanPostProcessor interface has the following two callback methods.

  • Object postProcessBeforeInitialization(Object bean, String beanName)- This callback method is called before container initialization methods (such as InitializingBean’s afterPropertiesSet() and any declared init method) are called
  • Object postProcessAfterInitialization(Object bean, String beanName) - This method is called after any bean initialization callbacks.

Configuring more than one BeanPostProcessor

You can configure multiple BeanPostProcessor instances. You can also control the order in which these BeanPostProcessors execute by setting the order property. For that the BeanPostProcessor implemenation class must implement the Ordered interface too.

Spring BeanPostProcessor Example

A typical use case for BeanPostProcessor is if you want to have some callback methods for specific type of bean.

Let’s say you have an interface IPayment and two implementation classes CashPayment and CardPayment. For these two beans only (out of all the configured beans) you want some logic to be performed (like doing some validation, checking some value) then you can create a BeanPostProcessor and in it’s callback method postProcessAfterInitialization you can use instanceOf operator to verify if bean is of specific type and then call the method you want.

Inerface IPayment

public interface IPayment extends PaymentCallBack {
 void executePayment();
}

Interface PaymentCallBack

public interface PaymentCallBack {
 void processInstance(IPayment bean);
}

CashPayment.java

public class CashPayment implements IPayment{
 public void executePayment() {
  System.out.println("Perform Cash Payment "); 
 }
 @PostConstruct
 public void annoInitMethod(){
  System.out.println("Calling InitMethod for CashPayment");
 }
 @Override
 public void processInstance(IPayment bean) {
  System.out.println("processInstance method called with bean " + bean);  
 }
}

CardPayment.java

public class CardPayment implements IPayment{
 public void executePayment() {
  System.out.println("Perform Card Payment "); 
 }
 @PostConstruct
 public void annoInitMethod(){
  System.out.println("Calling InitMethod for CardPayment");
 }
 @Override
 public void processInstance(IPayment bean) {
  System.out.println("processInstance method called with bean " + bean);
 }
}

In these classes you can see that Spring bean life cycle initialization method annotated with @PostConstruct is used to see when bean is actually initialized.

BeanPostProcessor Class

A custom bean post processor class in Spring implements BeanPostProcessor interface and provides implementation of callback methods postProcessBeforeInitialization() and postProcessAfterInitialization().

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class InstantiationBeanPostProcessor implements BeanPostProcessor, Ordered {

 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName)
   throws BeansException {
  System.out.println("In postProcessBeforeInitialization method");
  return bean;
 }

 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName)
   throws BeansException {

  System.out.println("In postProcessAfterInitialization method");
  if(bean instanceof IPayment){
   ((IPayment) bean).processInstance((IPayment)bean); 
  }
  return bean;
 }

 @Override
 public int getOrder() {
  // TODO Auto-generated method stub
  return 0;
 }
}

XML Configuration

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:util="http://www.springframework.org/schema/util" 
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  http://www.springframework.org/schema/util 
  http://www.springframework.org/schema/util/spring-util.xsd">
    
  <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
 
  <bean id="cashPaymentBean" class="org.netjs.exp.Spring_Example.CashPayment" />
  <bean id="cardPaymentBean" class="org.netjs.exp.Spring_Example.CardPayment" />
    
  <bean class="org.netjs.exp.Spring_Example.InstantiationBeanPostProcessor"/> 
</beans>

Notice how the InstantiationBeanPostProcessor is simply defined that's all is needed to register a BeanPostProcessor. It does not even have a name, and because it is a bean it can be dependency-injected just like any other bean.

You can use the following code to run the preceding code and configuration.
public class App {
 public static void main( String[] args ){
   
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
  //System.out.println("Loading AnnotationConfig app context");
  IPayment cashBean = (IPayment) context.getBean("cashPaymentBean");
  IPayment cardBean = (IPayment) context.getBean("cardPaymentBean");
  context.close();
 }
}

Output

In postProcessBeforeInitialization method
Calling InitMethod for CashPayment
In postProcessAfterInitialization method
processInstance method called with bean org.netjs.exp.Spring_Example.CashPayment@1e397ed7
In postProcessBeforeInitialization method
Calling InitMethod for CardPayment
In postProcessAfterInitialization method
processInstance method called with bean org.netjs.exp.Spring_Example.CardPayment@490ab905

That's all for this topic BeanPostProcessor in Spring Framework. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Bean Scopes in Spring With Examples
  2. Bean Definition Inheritance in Spring
  3. How to Inject Prototype Scoped Bean in Singleton Bean
  4. Lazy Initialization in Spring Using lazy-init And @Lazy Annotation
  5. Injecting Inner Bean in Spring

You may also like-

  1. Spring JdbcTemplate Insert, Update And Delete Example
  2. Run Time Injection Using Spring Expression Language(SpEL)
  3. Using depends-on Attribute in Spring
  4. Autodiscovery of Bean Using component-scan in Spring
  5. How ArrayList Works Internally in Java
  6. Object Cloning in Java
  7. Spliterator in Java
  8. static Block in Java

Wednesday, July 1, 2020

Python String replace() Method

Python String replace() method is used to replace occurrences of the specified substring with the new substring.

Syntax of replace() method

Syntax of replace() method is-

str.replace(old, new, count)

old- Specifies a substring that has to be replaced.

new- Specifies a substring that replaces the old substring.

count- count argument is optional if it is given, only the first count occurrences are replaced. If count is not specified then all the occurrences are replaced.

Return values of the method is a copy of the string with all occurrences of substring old replaced by new.

Replace() method Python examples

1. Replacing specified substring with new value.

def replace_sub(text):
    text = text.replace('30', 'thirty')
    print(text)

replace_sub('His age is 30')

Output

His age is thirty

2. replace() method with count parameter to replace only specified occurrences.

def replace_sub(text):
    text = text.replace('is', 'was')
    print(text)
    # replacing only one occurrence
    print(text.replace('was', 'is', 1))

replace_sub('His age is 30')

Output

Hwas age was 30
His age was 30

3. Replacing character with space.

def replace_sub(text):
    text = text.replace('H', '')
    print(text)

replace_sub('His age is 30')

Output

is age is 30

That's all for this topic Python String replace() Method. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Python Tutorial Page


Related Topics

  1. Removing Spaces From String in Python
  2. String Slicing in Python
  3. Python String isdigit() Method
  4. Python String isnumeric() Method
  5. Local, Nonlocal And Global Variables in Python

You may also like-

  1. Constructor in Python - __init__() function
  2. Installing Anaconda Distribution On Windows
  3. Python while Loop With Examples
  4. Multiple Inheritance in Python
  5. BigDecimal in Java
  6. Java Stream API Tutorial
  7. Difference Between Two Dates in Java
  8. Transaction Management in Spring