The active record pattern is an architectural pattern, commonly used in object-relational mapping (ORM) frameworks. It aims to bridge the gap between object-oriented programming and relational databases by representing database tables as classes and table rows as objects.
The pattern provides an easy-to-use API for database operations, allowing developers to interact with the database using objects.
Here's a basic example of how the active record pattern works in Java.
User.java
package com.sample.app.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.sample.app.util.DBConnectionUtil;
// Active Record class representing a "User" table in the database
public class User {
private static boolean USER_TABLE_CREATED = false;
private static AtomicInteger ID_COUNTER = new AtomicInteger(0);
private Integer id;
private String username;
private String email;
// Constructor
public User(int id, String username, String email) {
this.id = id;
this.username = username;
this.email = email;
}
public User(String username, String email) {
this.username = username;
this.email = email;
}
// Getters and setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// Save method to insert or update the record in the database
public static User save(User user) {
Integer newId = user.id;
try (Connection connection = DBConnectionUtil.connection()) {
if (user.id == null) {
// Insert new record
newId = ID_COUNTER.incrementAndGet();
String insertQuery = "INSERT INTO users (id, username, email) VALUES (?, ?, ?)";
try (PreparedStatement preparedStatement = connection.prepareStatement(insertQuery)) {
preparedStatement.setInt(1, newId);
preparedStatement.setString(2, user.getUsername());
preparedStatement.setString(3, user.getEmail());
preparedStatement.executeUpdate();
}
} else {
// Update existing record
String updateQuery = "UPDATE users SET username = ?, email = ? WHERE id = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(updateQuery)) {
preparedStatement.setString(1, user.getUsername());
preparedStatement.setString(2, user.getEmail());
preparedStatement.setInt(3, user.getId());
preparedStatement.executeUpdate();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return find(newId);
}
// Find method to retrieve a record by ID from the database
public static User find(int id) {
try (Connection connection = DBConnectionUtil.connection()) {
String selectQuery = "SELECT * FROM users WHERE id = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(selectQuery)) {
preparedStatement.setInt(1, id);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
// Map database columns to object properties
String username = resultSet.getString("username");
String email = resultSet.getString("email");
// Return a new User object
return new User(id, username, email);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
// Delete method to remove the record from the database
public static void delete(User user) {
try (Connection connection = DBConnectionUtil.connection()) {
String deleteQuery = "DELETE FROM users WHERE id = ?";
try (PreparedStatement preparedStatement = connection.prepareStatement(deleteQuery)) {
preparedStatement.setInt(1, user.getId());
preparedStatement.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static List<User> all() {
List<User> users = new ArrayList<>();
try (Connection connection = DBConnectionUtil.connection()) {
String deleteQuery = "SELECT * FROM users";
try (PreparedStatement preparedStatement = connection.prepareStatement(deleteQuery)) {
try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
// Map database columns to object properties
String username = resultSet.getString("username");
String email = resultSet.getString("email");
Integer id = resultSet.getInt("id");
// Return a new User object
users.add(new User(id, username, email));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
public static void createUserTable() {
if (USER_TABLE_CREATED) {
return;
}
try (Connection connection = DBConnectionUtil.connection()) {
String createTable = "CREATE TABLE users (id int, username varchar(50), email varchar(100), PRIMARY KEY(id))";
try (PreparedStatement preparedStatement = connection.prepareStatement(createTable)) {
preparedStatement.execute();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", email=" + email + "]";
}
}
In this example, the User class represents a user in a database with properties like id, username, and email. The class includes methods such as save, find, delete and all to perform database operations using JDBC. This example uses a simple H2 database connection, but you can adapt it to work with other databases or use an ORM (Object-Relational Mapping) library for more advanced features.
DBConnectionUtil.java
package com.sample.app.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnectionUtil {
public static Connection connection() throws SQLException {
return DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", "");
}
}
App.java
package com.sample.app;
import java.util.List;
import com.sample.app.entity.User;
public class App {
// Example usage
public static void main(String[] args) {
// 1. Create users table
User.createUserTable();
// Persist new users
User newUser1 = new User("Krishna", "krishna@example.com");
User newUser2 = new User("ptr", "ptr@example.com");
User newUser3 = new User("ram", "ram@example.com");
// Save users
User.save(newUser1);
User.save(newUser2);
User.save(newUser3);
List<User> allUsers = User.all();
System.out.println("\nAll the users :");
allUsers.stream().forEach(System.out::println);
// Retrieve the user by ID 1
User retrievedUser = User.find(1);
System.out.println("\nUser details for the id 1 is : " + retrievedUser);
System.out.println("\nUpdate the user email and username with id 1");
retrievedUser.setUsername("Joel");
retrievedUser.setEmail("joel@example.com");
User.save(retrievedUser);
retrievedUser = User.find(1);
System.out.println("\nUser details for the id 1 is : " + retrievedUser);
System.out.println("\nDelete the user with id 1");
User.delete(retrievedUser);
allUsers = User.all();
System.out.println("All the users :");
allUsers.stream().forEach(System.out::println);
}
}
Output
All the users : User [id=1, username=Krishna, email=krishna@example.com] User details for the id 1 is : User [id=1, username=Krishna, email=krishna@example.com] Update the user email and username with id 1 User details for the id 1 is : User [id=1, username=Joel, email=joel@example.com] Delete the user with id 1 All the users : User [id=2, username=ptr, email=ptr@example.com]
Note
Because the data and the database access methods are in the same file, those files end up being bigger.
You can download this example from this link.
No comments:
Post a Comment