Getting Started With HarperDB and Java: Your First "Hello, World" Integration
In this article, learn how HarperDB integrates with Java as a choice for building real-time and data-intensive applications.
Join the DZone community and get the full member experience.
Join For FreeIn today's data-driven world, the quest for efficient and flexible database solutions is an ongoing pursuit for developers and businesses alike. One such solution is HarperDB. HarperDB is a modern and versatile database management system with simplicity, speed, and scalability. In this article, we will delve into the world of HarperDB, exploring why it has gained popularity and what makes it a compelling choice for developers and organizations.
Additionally, we will take our first steps towards integrating HarperDB with the Java programming language. Java is a widely adopted, robust, and platform-independent programming language known for its reliability in building diverse applications. By bridging the gap between HarperDB and Java, we will unlock many possibilities for managing and accessing data seamlessly.
So, join us on this journey as we unravel HarperDB and embark on our first integration with plain Java. Discover how this combination can empower you to build efficient and responsive applications, streamline data management, and take your development projects to the next level.
HarperDB: A Modern Database Solution
HarperDB blends the simplicity of traditional functionality with the power and flexibility required by modern applications. Essentially, HarperDB is a globally distributed edge application platform comprised of an edge database, streaming broker, and user-defined applications, with near-zero latency, huge cost savings, and a superior developer experience. This versatility makes it an option for businesses and developers grappling with the complexities of managing diverse data sources.
HarperDB can run anywhere from edge to cloud, with a user-friendly management interface that enables developers of any skill level to get up and running quickly. Unlike many traditional databases that require extensive setup, configuration, and database administration expertise, HarperDB streamlines these processes. This simplicity reduces the learning curve and saves valuable development time, allowing teams to focus on building applications rather than managing the database.
Performance is critical to any database system, especially in today's real-time and data-intensive applications. HarperDB's architecture is designed for speed and scale, ensuring that data retrieval and processing happens at lightning speed. HarperDB offers horizontal scalability, allowing you to add resources seamlessly as your data grows.
HarperDB goes beyond pigeonholing data into predefined structures. This flexibility is precious in today's data landscape, where information comes in diverse formats. With HarperDB, you can store, query, and analyze data in a way that aligns with your application's unique requirements without being constrained by rigid schemas.
HarperDB enables cost savings in numerous ways. The ease of use and low maintenance requirements translate into reduced operational expenses. Additionally, HarperDB delivers the same throughput as existing solutions with less hardware (or enables you to use the same amount of hardware and have greater throughput).
As we delve deeper into HarperDB's integration with Java, we will unlock the potential of this database system and explore how it can elevate your data projects to new heights.
Installing HarperDB Locally
In our exploration of HarperDB and its integration with Java, one of the first steps is to install HarperDB locally. While a cloud version is available, this article focuses on the local installation to provide you with hands-on experience.
You can choose your preferred flavor and installation method from the official documentation here. However, for simplicity, we’ll demonstrate how to set up HarperDB using Docker, a popular containerization platform.
Docker Installation
Docker simplifies the process of installing and running HarperDB in a containerized environment. Please note that the following Docker command is for demonstration purposes and should not be used in production. In production, you should follow best practices for securing your database credentials.
Here’s how to run HarperDB in a Docker container with a simple username and password:
docker run -d \
-e HDB_ADMIN_USERNAME=root \
-e HDB_ADMIN_PASSWORD=password \
-e HTTP_THREADS=4 \
-p 9925:9925 \
-p 9926:9926 \
harperdb/harperdb
Let’s break down what this command does:
-d
: Runs the container in detached mode (in the background)-e HDB_ADMIN_USERNAME
=root:
Sets the admin username toroot
(you can change this)-e HDB_ADMIN_PASSWORD
=password
: Sets the admin password topassword
(remember to use a robust and secure password in production)-e HTTP_THREADS=4
: Configures the number of HTTP threads for handling requests-p 9925:9925
and-p 9926:9926
: Maps the container’s internal ports9925
and9926
to the corresponding ports on your host machine
This local installation will serve as the foundation for exploring HarperDB’s capabilities and its integration with Java. In subsequent sections, we will dive deeper into using HarperDB and connecting it with Java to leverage its features for building robust and data-driven applications.
Creating Schema, Table, and Fields in HarperDB
Now that we have HarperDB running locally, let’s create a schema and table and define the fields for our “dev”
schema and “person”
table. We’ll perform these operations using HTTP requests. Please note that the authorization header in these requests uses a primary authentication method with the username “root”
and password “password”
. In a production environment, always ensure secure authentication methods.
To start working with HarperDB locally, we must create a schema, define a table, and specify its fields. These operations can be performed through HTTP requests. In our example, we’ll create a dev
schema and a "person"
table with "id"
, "name"
, and "age"
columns. We’ll use curl
commands for this purpose.
Before running these commands, ensure that your HarperDB Docker container is up and running, as explained earlier.
Creating a Schema (‘dev’):
curl --location --request POST 'http://localhost:9925/' \
--header 'Authorization: Basic cm9vdDpwYXNzd29yZA==' \
--header 'Content-Type: application/json' \
--data-raw '{
"operation": "create_schema",
"schema": "dev"
}'
This command sends an HTTP POST
request to create a dev
schema. The authorization header includes the basic authentication credentials (Base64 encoded username and password). Replace cm9vdDpwYXNzd29yZA==
with your base64-encoded credentials.
Creating a "person" Table With "id" as the Hash Attribute:
curl --location 'http://localhost:9925' \
--header 'Authorization: Basic cm9vdDpwYXNzd29yZA==' \
--header 'Content-Type: application/json' \
--data '{
"operation": "create_table",
"schema": "dev",
"table": "person",
"hash_attribute": "id"
}'
This command creates a "person"
table within the "dev"
schema and designates the "id"
column as the hash attribute. The "hash_attribute"
is used for distributed data storage and retrieval.
Creating "name" and "age" Columns in the "person" Table:
curl --location 'http://localhost:9925' \
--header 'Authorization: Basic cm9vdDpwYXNzd29yZA==' \
--header 'Content-Type: application/json' \
--data '{
"operation": "create_attribute",
"schema": "dev",
"table": "person",
"attribute": "name"
}'
curl --location 'http://localhost:9925' \
--header 'Authorization: Basic cm9vdDpwYXNzd29yZA==' \
--header 'Content-Type: application/json' \
--data '{
"operation": "create_attribute",
"schema": "dev",
"table": "person",
"attribute": "age"
}'
These two commands create "name"
and "age"
columns within the "person"
table. These columns define the structure of your data.
With these HTTP requests, you’ve set up the schema, table, and columns in your local HarperDB instance. You are now ready to start working with data and exploring how to integrate HarperDB with Java for powerful data-driven applications.
Exploring the Java Code for HarperDB Integration
This session will explore the Java code to integrate HarperDB into a plain Java SE (Standard Edition) application. We will create a simple “Person”
entity with “id”
, “name”
, and “age”
fields. We must set up a Maven project and include the HarperDB JDBC driver to start.
Step 1: Create a Maven Project
- Begin by creating a new Maven project using the Maven Quickstart Archetype. You can use the following command to create the project:
mvn archetype:generate -DgroupId=com.example -DartifactId=harperdb-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
- This command will generate a basic Maven project structure.
- Navigate to the project root directory.
Step 2: Include the HarperDB JDBC Driver
- Download the HarperDB JDBC driver from the official HarperDB resources page: HarperDB Drivers.
- Extract the contents of the downloaded ZIP file.
- Create a new folder named lib in your project root directory.
- Copy the HarperDB JDBC driver JAR file from the extracted contents and paste it into the lib folder.
Step 3: Update the Maven POM File
- Open the pom.xml file in your project.
- Add the following Maven dependency to include the HarperDB JDBC driver. Make sure to adjust the
<version>
and<systemPath>
to match your JAR file:
<dependency>
<groupId>cdata.jdbc.harperdb</groupId>
<artifactId>cdata.jdbc.harperdb</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${project.basedir}/lib/cdata.jdbc.harperdb.jar</systemPath>
</dependency>
This dependency instructs Maven to include the HarperDB JDBC driver JAR file as a system dependency for your project.
Creating a Person Record and a PersonDAO Class for HarperDB Integration
We will create a Person
record, an immutable class introduced in Java for data modeling. We will also implement a PersonDAO
class to interact with HarperDB using direct JDBC API calls.
1. Create the Person Record
First, we define the Person
record with three attributes: id
, name
, and age
. We also provide a static factory method of
for creating Person
instances. This record simplifies data modeling and reduces code by automatically generating a constructor, accessor methods, and equals()
and hashCode()
implementations.
public record Person(String id, String name, Integer age) {
public static Person of(String name, Integer age) {
return new Person(null, name, age);
}
}
2. Create the PersonDAO Class
Next, we create the PersonDAO
class, responsible for database operations using the HarperDB JDBC driver. This class provides methods for inserting, finding by ID, deleting, and retrieving all Person
records from the database.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
public class PersonDAO {
private static final String INSERT = "INSERT INTO dev.person (name, age) VALUES (?, ?)";
private static final String SELECT = "select * From dev.person";
private static final String FIND_ID = "select * From dev.person where id = ?";
private static final String DELETE = "delete From dev.person where id = ?";
public void insert(Person person) throws SQLException {
try(Connection connection = createConnection()){
var statement = connection.prepareStatement(INSERT);
statement.setString(1, person.name());
statement.setInt(2, person.age());
statement.execute();
}
}
public Optional<Person> findById(String id) throws SQLException {
try(Connection connection = createConnection()) {
var statement = connection.prepareStatement(FIND_ID);
statement.setString(1, id);
var resultSet = statement.executeQuery();
if(resultSet.next()) {
var name = resultSet.getString("name");
var age = resultSet.getInt("age");
return Optional.of(new Person(id, name, age));
}
return Optional.empty();
}
}
public void delete(String id) throws SQLException {
try(Connection connection = createConnection()) {
var statement = connection.prepareStatement(DELETE);
statement.setString(1, id);
statement.execute();
}
}
public List<Person> findAll() throws SQLException {
List<Person> people = new ArrayList<>();
try(Connection connection = createConnection()) {
var statement = connection.prepareStatement(SELECT);
var resultSet = statement.executeQuery();
while (resultSet.next()) {
var id = resultSet.getString("id");
var name = resultSet.getString("name");
var age = resultSet.getInt("age");
people.add(new Person(id, name, age));
}
}
return people;
}
static Connection createConnection() throws SQLException {
var properties = new Properties();
properties.setProperty("Server","http://localhost:9925/");
properties.setProperty("User","root");
properties.setProperty("Password","password");
return DriverManager.getConnection("jdbc:harperdb:", properties);
}
}
With the Person
record and PersonDAO
class in place, you can now interact with HarperDB using Java, performing operations such as inserting, finding by ID, deleting, and retrieving Person
records from the database. Adjust the database connection properties in the createConnection
method to match your HarperDB setup.
Executing the Java Application with HarperDB Integration
With your Person record and PersonDAO class in place, you can execute the Java application to interact with HarperDB. Here’s your App class for implementing the application:
import java.sql.SQLException;
import java.util.List;
public class App {
public static void main(String[] args) throws SQLException {
PersonDAO dao = new PersonDAO();
dao.insert(Person.of( "Ada", 10));
dao.insert(Person.of("Poliana", 20));
dao.insert(Person.of("Jhon", 30));
List<Person> people = dao.findAll();
people.forEach(System.out::println);
System.out.println("Find by id: ");
var id = people.get(0).id();
dao.findById(id).ifPresent(System.out::println);
dao.delete(id);
System.out.println("After delete: is present? " + dao.findById(id).isPresent());
}
private App() {
}
}
In this App
class:
- We create an instance of the
PersonDAO
class to interact with the database. - We insert sample
Person
records using thedao.insert(...)
method. - We retrieve all
Person
records usingdao.findAll()
and print them. - We find a
Person
by ID and print it usingdao.findById(...)
. - We delete a
Person
by ID usingdao.delete(...)
and then check if it’s still in the database.
Executing this App
class will perform these operations against your HarperDB database, demonstrating how your Java application can interact with HarperDB using the Person
record and PersonDAO
class for database operations. Make sure to have HarperDB running and the HarperDB JDBC driver adequately configured in your project, as mentioned earlier in the article.
Conclusion
In our journey to explore HarperDB and its integration with Java, we’ve discovered a versatile and modern database solution that combines simplicity, speed, and flexibility to meet a wide range of data management needs. In our conclusion, we recap what we’ve learned and highlight the resources available for further exploration.
Next Steps
- Documentation: For a deeper dive into HarperDB’s features and capabilities, consult the official documentation at HarperDB Documentation (linked earlier in this article).
- Sample Code: Explore practical examples and sample code for integrating HarperDB with Java in the HarperDB Samples GitHub Repository.
Incorporating HarperDB into your Java applications empowers you to manage data efficiently, make informed decisions in real time, and build robust, data-driven solutions. Whether you’re developing IoT applications, web and mobile apps, or a global gaming solution, HarperDB is a modern and accessible choice.
Opinions expressed by DZone contributors are their own.
Comments