This page will introduce examples of Spring Boot and HikariCP.
HikariCP is a fast, simple, reliable and production ready JDBC connection pool.
In spring boot version 2.0, the default database connection pool technology has been switched from Tomcat pool to HikariCP.
This is because HikariCP provides excellent performance.
Now, since the release of Spring Boot 2.0, spring boot starter JDBC and spring boot starter data JPA solve the dependency of HikariCP by default, and the default value of spring.datasource.type attribute is HikariDataSource.
Spring boot first selects HikariCP, then Tomcat pool, and finally Commons DBCP2 (based on availability).
On this page, we will provide complete examples of HikariCP, Spring Boot data and MySQL.
We will create a demo application where we will perform create and read operations in the database.
We will configure HikariCP properties in the application.properties file, such as connectionTimeout, minimumIdle, maxPoolSize, idleTimeout, maxLifetime, and autoCommit.
Sample tool version- Java 9
- Spring 5.0.7.RELEASE
- Spring Boot 2.0.3.RELEASE
- Maven 3.5.2
- MySQL 5.5
- Eclipse Oxygen
Before using HikariCP, we need to ensure that we have solved the HikariCP dependency.
If we are using Maven, we can use the following dependencies.
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.1.0</version> </dependency>
If we are using Spring Boot 2.0 or later, we do not need to add HikariCP dependency in pom.xml or build.gradle, because spring boot starter JDBC and spring boot starter data JPA will solve it by default.
This means that if the dependency we use is
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <version>2.0.3.RELEASE</version> </dependency>
perhaps
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <version>2.0.3.RELEASE</version> </dependency>
Then we don't need to include HikariCP dependencies in pom.xml or build.gradle.
HikariCP configurationFor the configuration of Hikari connection pool, we enable it by using spring.datasource.type and specifying the fully qualified name of the connection pool implementation in the application.properties file, as shown below.
spring.datasource.type = com.zaxxer.hikari.HikariDataSource
If we use Spring Boot version 2.0 and later, Spring Boot will select HikariDataSource by default. We do not need to configure the above line.
Now to configure Hikari specific connection pool settings, Spring Boot provides the prefix spring.datasource.hikari. *, which can be used in the application.properties file.
We will discuss some frequently used configurations here.
1. connectionTimeout
connectionTimeout is the maximum number of milliseconds that a client waits for a connection from the connection pool. We need to configure it as follows.
spring.datasource.hikari.connection-timeout=20000
2. minimumIdle
minimumIdle is the minimum number of free connections maintained by HikariCP in the connection pool. It is configured as follows.
spring.datasource.hikari.minimum-idle=5
3. maximumPoolSize
maximumPoolSize configures the maximum number and size of connection pools. Its configuration method is as follows.
spring.datasource.hikari.maximum-pool-size=12
4. idleTimeout
idleTimeout is the maximum time that a connection is allowed to idle in the connection pool, in milliseconds. Its configuration method is as follows.
spring.datasource.hikari.idle-timeout=300000
5. maxLifetime
maxLifetime is the maximum lifetime (in milliseconds) after a connection in the pool is closed. Its configuration is shown below.
spring.datasource.hikari.max-lifetime=1200000
The connection in use will never fail and will be deleted after the maximum lifetime only when it is closed.
6. autoCommit
autoCommit configures the default autoCommit behavior for connections returned from the pool. The default value is true.
spring.datasource.hikari.auto-commit=trueSpring Boot Data + HikariCP + MySQL example
We will create a Spring Boot REST web service with Spring Boot Data, HikariCP and MySQL.
We will use CrudRepository to query the database.
We will also use RestTemplate to create a REST client to test our application.
First, find the project structure of the demo application.
Find the MySQL table structure used in our example.
MySQL Table: articles
CREATE TABLE `articles` ( `article_id` INT(5) NOT NULL AUTO_INCREMENT, `title` VARCHAR(200) NOT NULL, `category` VARCHAR(100) NOT NULL, PRIMARY KEY (`article_id`) ) COLLATE='latin1_swedish_ci' ENGINE=InnoDB;
Locate the Maven file to resolve the dependency issue.
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>com.concretepage</groupId> <artifactId>spring-boot-app</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-app</name> <description>Spring Boot Application</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> </parent> <properties> <java.version>9</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>6.0.5</version> </dependency> <!-- Spring Boot Data 2.0 includes HikariCP by default --> <!-- dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.1.0</version> </dependency --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
If the Spring Boot version we use is lower than Spring Boot 2.0, we need to introduce the HikariCP dependency, as shown below.
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.1.0</version> </dependency>
HikariCP 3.1.0 is applicable to Java 8 and Java 9.
Now find the properties file to configure the data source and other properties.
The connection pool will be configured using HikariCP.
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/concretepage spring.datasource.username=root spring.datasource.password=cp #Spring Boot 2.0 includes HikariDataSource by default #spring.datasource.type = com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.connection-timeout=20000 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.maximum-pool-size=12 spring.datasource.hikari.idle-timeout=300000 spring.datasource.hikari.max-lifetime=1200000 spring.datasource.hikari.auto-commit=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect spring.jpa.properties.hibernate.id.new_generator_mappings=false spring.jpa.properties.hibernate.format_sql=true
If the Spring Boot version we use is lower than Spring Boot 2.0, we need to add the spring.datasource.type attribute for HikariCP, as shown below.
spring.datasource.type = com.zaxxer.hikari.HikariDataSource
Now find the other files used in the demo.
ArticleRepository.java
package com.concretepage.repository; import org.springframework.data.repository.CrudRepository; import com.concretepage.entity.Article; public interface ArticleRepository extends CrudRepository<Article, Long> { }
Article.java
package com.concretepage.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="articles") public class Article implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="article_id") private long articleId; @Column(name="title") private String title; @Column(name="category") private String category; public long getArticleId() { return articleId; } public void setArticleId(long articleId) { this.articleId = articleId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
IArticleService.java
package com.concretepage.service; import java.util.List; import com.concretepage.entity.Article; public interface IArticleService { List<Article> getAllArticles(); void addArticle(Article article); }
ArticleService.java
package com.concretepage.service; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.concretepage.entity.Article; import com.concretepage.repository.ArticleRepository; @Service public class ArticleService implements IArticleService { @Autowired private ArticleRepository articleRepository; @Override public List<Article> getAllArticles(){ List<Article> list = new ArrayList<>(); articleRepository.findAll().forEach(e -> list.add(e)); return list; } @Override public void addArticle(Article article){ articleRepository.save(article); } }
ArticleInfo.java
package com.concretepage.controller; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; public class ArticleInfo { @JsonInclude(Include.NON_NULL) private long articleId; @JsonInclude(Include.NON_NULL) private String title; @JsonInclude(Include.NON_NULL) private String category; public long getArticleId() { return articleId; } public void setArticleId(long articleId) { this.articleId = articleId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
ArticleController.java
package com.concretepage.controller; import java.util.ArrayList; import java.util.List; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; import com.concretepage.entity.Article; import com.concretepage.service.IArticleService; @RestController @RequestMapping("user") public class ArticleController { @Autowired private IArticleService articleService; //Fetches all articles @GetMapping(value= "articles") public ResponseEntity<List<ArticleInfo>> getAllArticles() { List<ArticleInfo> responseArticleList = new ArrayList<>(); List<Article> articleList = articleService.getAllArticles(); for (int i = 0; i < articleList.size(); i++) { ArticleInfo ob = new ArticleInfo(); BeanUtils.copyProperties(articleList.get(i), ob); responseArticleList.add(ob); } return new ResponseEntity<List<ArticleInfo>>(responseArticleList, HttpStatus.OK); } //Creates a new article @PostMapping(value= "article") public ResponseEntity<Void> addArticle(@RequestBody ArticleInfo articleInfo, UriComponentsBuilder builder) { Article article = new Article(); BeanUtils.copyProperties(articleInfo, article); articleService.addArticle(article); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/article/").buildAndExpand(article.getArticleId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } }
Now find the Main method of the Java class to run the application. To ensure that we are using HikariCP, we print the data source name.
SpringBootAppStarter.java
package com.concretepage; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootAppStarter implements CommandLineRunner { @Autowired DataSource dataSource; public static void main(String[] args) throws Exception { SpringApplication.run(SpringBootAppStarter.class, args); } @Override public void run(String... args) throws Exception { System.out.println("DataSource = " + dataSource); } }
When we start our application, we can see the following information in the console at the end of the server log.
output
DataSource = HikariDataSource (HikariPool-1)
Now find the REST client to test the application.
RestClientUtil.java
package com.concretepage.client; import java.net.URI; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import com.concretepage.entity.Article; public class RestClientUtil { public void getAllArticlesDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/user/articles"; HttpEntity<String> requestEntity = new HttpEntity<String>(headers); ResponseEntity<Article[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article[].class); Article[] articles = responseEntity.getBody(); for(Article article : articles) { System.out.println("Id:"+article.getArticleId()+", Title:"+article.getTitle() +", Category: "+article.getCategory()); } } public void addArticleDemo() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/user/article"; Article objArticle = new Article(); objArticle.setTitle("Spring REST Security using Hibernate"); objArticle.setCategory("Spring"); HttpEntity<Article> requestEntity = new HttpEntity<Article>(objArticle, headers); URI uri = restTemplate.postForLocation(url, requestEntity); System.out.println(uri.getPath()); } public static void main(String args[]) { RestClientUtil util = new RestClientUtil(); util.addArticleDemo(); util.getAllArticlesDemo(); } }
When we run the client, we will get the following output.
output
Id:1, Title:Spring REST Security using Hibernate, Category: SpringTest application
To test the application, first create a table in MySQL according to the method given in the article, and configure your database credentials in the application.properties file. Then, we can run REST network services in the following ways.
1. Use the Maven command
Download the source code of the project. Use the command prompt to go to the root folder of the project and run the command.
mvn spring-boot:run
The Tomcat server will be started.
2. Use Eclipse
Use the download link at the end of the article to download the source code of the project. Import the project into eclipse. Using the command prompt, go to the root folder of the project and run.
mvn clean eclipse:eclipse
Then refresh the project in eclipse. Click Run as - > java application to run the main class SpringBootAppStarter. The Tomcat server will be started.
3. Use executable jars
Using the command prompt, go to the root folder of the project and run the command.
mvn clean package
We will get the executable JAR file spring-boot-app-0.0.1-SNAPSHOT.jar in the target folder. Run the JAR as follows.
java -jar target/spring-boot-app-0.0.1-SNAPSHOT.jar
The Tomcat server will be started.
Now we are ready to test the application. To run the Web service client, enter the RestClientUtil class in eclipse and click Run as - > java application.
reference[1]Spring Boot Reference Guide
[2]HikariCP
[3]Spring Boot 2.0 Release Notes
[4]Spring Boot + HikariCP