Mastering Database Persistence in Java: JDBC, JPA, and Hibernate
JDBC (Java Database Connectivity)
JDBC is the lowest-level API for database interaction in Java introduced in JDK 1.1.
Key Concepts
- DriverManager: Establishes a connection to the database.
- Connection: Represents the connection to the database.
- Statement & PreparedStatement: Execute SQL queries.
- ResultSet: Holds query results.
- Transactions: Commit or rollback operations.
Example
package org.example.loginpage.dbConnection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DbConnection {
private static final String URL = "jdbc:mysql://localhost:3306/avocado_login";
private static final String USER = "mysql";
private static final String PASSWORD = "root";
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
JPA (Java Persistence API)
JPA is a specification for managing relational data in Java applications using ORM.
Why ORM?
Object-Relational Mapping (ORM) is a technique used to convert data between relational databases and object-oriented programming languages like Java. It simplifies database interactions by allowing developers to work with Java objects instead of SQL queries.
Key Annotations
@Entity
- Defines a persistent entity.
@Table(name = "table_name")
- Specifies the table.
@Id
- Declares the primary key.
@GeneratedValue(strategy = GenerationType.IDENTITY)
- Auto-generates ID values.
@OneToMany
, @ManyToOne
- Defines relationships between entities.
Handling Relationships in ORM
- One-to-One (
@OneToOne
): Maps a single record in one table to a single record in another table.
- One-to-Many (
@OneToMany
): Maps a single record in one table to multiple records in another table.
- Many-to-One (
@ManyToOne
): Maps multiple records in one table to a single record in another table.
- Many-to-Many (
@ManyToMany
): Maps multiple records in one table to multiple records in another table using a join table.
Entity Class Example
package com.example.meroPASAL.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.math.BigDecimal;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class CartItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int quantity;
private BigDecimal unitPrice;
private BigDecimal totalPrice;
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
@JsonIgnore
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "cart_id")
private Cart cart;
public void setTotalPrice() {
this.totalPrice = this.unitPrice.multiply(new BigDecimal(quantity));
}
}
JPA Repository Example
package com.example.meroPASAL.repository;
import com.example.meroPASAL.model.CartItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CartItemRepository extends JpaRepository<CartItem, Long> {
}
Hibernate (JPA Implementation)
Hibernate is an ORM framework that implements JPA, simplifying database interactions.
Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/meropasal
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA and Hibernate Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Drawbacks of ORM
- Performance Overhead: ORM frameworks generate SQL dynamically, which may not be as optimized as hand-written queries.
- Complex Queries: Handling complex queries can be challenging as ORM hides SQL details.
- Learning Curve: Developers need to understand both ORM concepts and the underlying database interactions.