Java JDBC CRUD Operations | Database Sinhala Tutorial | දත්ත සමුදා සම්බන්ධතා

Java JDBC CRUD Operations | Database Sinhala Tutorial | දත්ත සමුදා සම්බන්ධතා

ආයුබෝවන් යාළුවනේ!

අද අපි කතා කරන්න යන්නේ ඕනෑම software application එකක හදවත වගේ වැදගත් දෙයක් ගැන. ඒ තමයි Database එකක් එක්ක වැඩ කරන එක! අපි දන්නවා මොන වගේ application එකක් හැදුවත්, data save කරගන්න, ආයෙත් ගන්න, update කරන්න, නැත්නම් delete කරන්න වගේ දේවල් කරන්න ඕනේ වෙනවා. මේවට තමයි CRUD Operations (Create, Read, Update, Delete) කියලා කියන්නේ.

Java වල මේ දේවල් පහසුවෙන් කරන්න පුළුවන් API එකක් තියෙනවා. ඒක තමයි JDBC (Java Database Connectivity). අද මේ guide එකෙන් අපි බලමු JDBC පාවිච්චි කරලා database එකක් එක්ක සම්බන්ධයක් ගොඩනගාගෙන, ඒ CRUD Operations ටික කොහොමද හරියටම කරන්නේ කියලා. අපි මේක පියවරෙන් පියවරට, practical විදියට, code examples එක්කම ඉගෙනගමු. කම්මැලි නැතුව කියවන්න! මේක අනිවාර්යයෙන්ම ඔබේ software engineering දැනුමට ලොකු වටිනාකමක් එකතු කරයි!

1. JDBC කියන්නේ මොකක්ද?

සරලවම කිව්වොත්, JDBC කියන්නේ Java application එකකට database එකක් එක්ක කතා කරන්න පුළුවන් කරන API (Application Programming Interface) එකක්. හරියට භාෂා පරිවර්තකයෙක් වගේ. අපේ Java code එකෙන් දෙන instructions, database එකට තේරෙන භාෂාවට (SQL) හරවලා දෙනවා, database එකෙන් එන උත්තර ආයෙත් Java code එකට තේරෙන විදියට හරවලා දෙනවා.

JDBC API එක java.sql සහ javax.sql packages වලින් තමයි හැදිලා තියෙන්නේ. මේකේ තියෙන interfaces සහ classes පාවිච්චි කරලා තමයි අපි database එකක් එක්ක connect වෙන්නේ, queries run කරන්නේ, results analyze කරන්නේ වගේ දේවල් කරන්නේ.

වැදගත් දේ තමයි, JDBC එකට driver එකක් ඕනේ වෙනවා. හැම database වර්ගයකටම (MySQL, PostgreSQL, Oracle, SQL Server වගේ) වෙනම JDBC driver එකක් තියෙනවා. මේ driver එක තමයි JDBC API එකයි database එකයි අතර පාලම විදියට වැඩ කරන්නේ.

2. Database Setup & Project Configuration

හරි, දැන් අපි නිකන් කතා කරලා වැඩක් නෑ. මේක practical විදියට කරලා බලමු. අපි MySQL database එකක් පාවිච්චි කරමු. ඔබට XAMPP, WAMP වගේ එකක් පාවිච්චි කරලා local machine එකේ MySQL server එකක් install කරගන්න පුළුවන්. නැත්නම් Docker වගේ එකක් පාවිච්චි කරන්නත් පුළුවන්.

2.1. MySQL Database එකක් හදමු

මුලින්ම අපි අපේ project එකට ඕන කරන database එකයි, table එකයි හදාගමු. MySQL client එකක් (phpMyAdmin, MySQL Workbench, or command line) පාවිච්චි කරලා මේ SQL queries ටික run කරන්න:

CREATE DATABASE school_db;
USE school_db;

CREATE TABLE students (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INT,
    grade VARCHAR(10)
);

මේකෙන් අපි school_db කියලා database එකක් හදලා, ඒක ඇතුලේ students කියලා table එකක් හැදුවා. ඒකේ id, name, age, grade කියන columns ටික තියෙනවා.

2.2. JDBC Driver එක දාගමු

දැන් අපේ Java project එකට MySQL JDBC driver එක එකතු කරගන්න ඕනේ. මේක සාමාන්‍යයෙන් JAR file එකක් විදියට එන්නේ. ඔබට Maven හෝ Gradle වගේ build tool එකක් පාවිච්චි කරනවා නම්, pom.xml (Maven) හෝ build.gradle (Gradle) file එකට dependency එකක් විදියට එකතු කරන්න පුළුවන්.

Maven සඳහා:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version> <!-- Latest version එකක් දාන්න -->
</dependency>

Gradle සඳහා:

implementation 'mysql:mysql-connector-java:8.0.28' <!-- Latest version එකක් දාන්න -->

නැත්නම්, ඔබට MySQL Connector/J JAR file එක download කරලා, ඔබේ IDE එකේ project classpath එකට අතින්ම add කරන්න පුළුවන් (Eclipse, IntelliJ IDEA වගේ IDE වල Library settings වලට ගිහින්). version එක ගැන සැලකිලිමත් වෙන්න, හැමවිටම latest stable version එක පාවිච්චි කරන්න බලන්න.

3. Database Connection එකක් හදමු

දැන් අපි database එකට connect වෙන්න අවශ්‍ය code එක ලියමු. මේක වෙනම utility class එකක් විදියට හදන එක හොඳ practice එකක්. එතකොට අපිට ඕනෑම තැනකින් connection එකක් ඉල්ලගන්න පුළුවන්.

3.1. DBConnection Class එක

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnection {
    // Database URL, Username, and Password
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/school_db?useSSL=false&serverTimezone=UTC";
    private static final String USER = "root"; // ඔබේ MySQL username එක
    private static final String PASSWORD = ""; // ඔබේ MySQL password එක ( හිස්ව තැබිය හැක ඔබ XAMPP වැනි දේකට password නොදුන්නේ නම් )

    public static Connection getConnection() {
        Connection connection = null;
        try {
            // Database Driver එක Load කිරීම (නව JDBC versions වල අනිවාර්ය නැත)
            // Class.forName("com.mysql.cj.jdbc.Driver");
            
            // Database එකට සම්බන්ධ වීම
            connection = DriverManager.getConnection(JDBC_URL, USER, PASSWORD);
            System.out.println("Database connection successful!");
        } catch (SQLException e) {
            System.err.println("Error connecting to the database: " + e.getMessage());
            // දෝෂය පිළිබඳව වැඩිදුර තොරතුරු පෙන්වීම
            e.printStackTrace();
        }
        return connection;
    }

    public static void closeConnection(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
                System.out.println("Database connection closed.");
            } catch (SQLException e) {
                System.err.println("Error closing the database connection: " + e.getMessage());
            }
        }
    }
}

මේ class එකේදී අපි:

  • JDBC_URL, USER, PASSWORD කියන constants තුන define කරලා තියෙනවා. මේවා ඔබේ database settings අනුව වෙනස් කරන්න.
  • getConnection() method එකෙන් database එකට connection එකක් හදනවා. මෙතන DriverManager.getConnection() තමයි key method එක.
  • closeConnection() method එකෙන් connection එක වහනවා. මේක වැදගත්, මොකද විවෘත connections වැඩියෙන් තියාගත්තොත් resource leak වෙන්න පුළුවන්.
  • Error handling සඳහා try-catch blocks පාවිච්චි කරලා තියෙනවා.

4. Implementing CRUD Operations

දැන් අපි අපේ core task එකට යමු - CRUD Operations implement කරන එක. මේ සඳහා අපි DAO (Data Access Object) Design Pattern එක පාවිච්චි කරමු. මේකෙන් database operations application logic එකෙන් වෙන් කරලා තියන්න පුළුවන්. එතකොට code එක clean වෙනවා, maintain කරන්නත් ලේසියි.

4.1. Create (Data Insert කිරීම)

Database එකට අලුත් data ඇතුළු කරන්න අපි INSERT SQL statement එකක් පාවිච්චි කරනවා. මෙතනදී PreparedStatement එකක් පාවිච්චි කරන එක ඉතාම වැදගත්. ඒකෙන් SQL injection attacks වලින් ආරක්ෂා වෙන්න පුළුවන්, වගේම queries වල performance එකත් වැඩි දියුණු වෙනවා.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class StudentDAO {

    public void addStudent(String name, int age, String grade) {
        String INSERT_SQL = "INSERT INTO students (name, age, grade) VALUES (?, ?, ?)";
        // try-with-resources statement එක මගින් connection සහ preparedStatement ස්වයංක්‍රීයව close වේ.
        try (Connection connection = DBConnection.getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(INSERT_SQL)) {

            preparedStatement.setString(1, name);
            preparedStatement.setInt(2, age);
            preparedStatement.setString(3, grade);

            int rowsAffected = preparedStatement.executeUpdate();
            if (rowsAffected > 0) {
                System.out.println(name + " added successfully.");
            } else {
                System.out.println("Failed to add " + name + ".");
            }

        } catch (SQLException e) {
            System.err.println("Error adding student: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

try-with-resources කියන්නේ Java 7 වලින් ආපු නියම feature එකක්. මේක පාවිච්චි කරනකොට, try block එක අවසානයේදී resources (Connection, PreparedStatement වගේ) ස්වයංක්‍රීයව close වෙනවා. ඒකෙන් code එක clean වෙනවා, වගේම resource leaks වළක්වාගන්නත් පුළුවන්.

4.2. Read (Data ලබාගැනීම)

Database එකෙන් data කියවන්න අපි SELECT SQL statement එකක් පාවිච්චි කරනවා. මේකෙන් ලැබෙන results ResultSet object එකක තියෙනවා.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class StudentDAO { 
    // ... addStudent method එක මෙතනට උඩින් ...

    public void getAllStudents() {
        String SELECT_SQL = "SELECT id, name, age, grade FROM students";
        try (Connection connection = DBConnection.getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(SELECT_SQL);
             ResultSet resultSet = preparedStatement.executeQuery()) { // SELECT query සඳහා executeQuery()

            System.out.println("\n--- All Students ---");
            while (resultSet.next()) { // ResultSet එකේ record එකින් එකට යනවා
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                String grade = resultSet.getString("grade");
                System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age + ", Grade: " + grade);
            }
            System.out.println("--------------------");

        } catch (SQLException e) {
            System.err.println("Error retrieving students: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    public void getStudentById(int studentId) {
        String SELECT_BY_ID_SQL = "SELECT id, name, age, grade FROM students WHERE id = ?";
        try (Connection connection = DBConnection.getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(SELECT_BY_ID_SQL)) {
            
            preparedStatement.setInt(1, studentId);
            try (ResultSet resultSet = preparedStatement.executeQuery()) {
                if (resultSet.next()) {
                    int id = resultSet.getInt("id");
                    String name = resultSet.getString("name");
                    int age = resultSet.getInt("age");
                    String grade = resultSet.getString("grade");
                    System.out.println("\n--- Student Found (ID: " + studentId + ") ---");
                    System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age + ", Grade: " + grade);
                    System.out.println("---------------------------");
                } else {
                    System.out.println("No student found with ID: " + studentId);
                }
            }
        } catch (SQLException e) {
            System.err.println("Error retrieving student by ID: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

resultSet.next() method එකෙන් කියන්නේ ResultSet එකේ ඊළඟ record එකක් තියෙනවද කියලා. තියෙනවා නම් true return කරනවා, නැත්නම් false. getInt(), getString() වගේ methods පාවිච්චි කරලා අපිට column values ලබාගන්න පුළුවන්. ඒ column name එක හරි, column index එක හරි පාවිච්චි කරන්න පුළුවන්.

4.3. Update (Data වෙනස් කිරීම)

තිබෙන data වෙනස් කරන්න අපි UPDATE SQL statement එකක් පාවිච්චි කරනවා.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class StudentDAO { 
    // ... addStudent, getAllStudents, getStudentById methods මෙතනට උඩින් ...

    public void updateStudentGrade(int studentId, String newGrade) {
        String UPDATE_SQL = "UPDATE students SET grade = ? WHERE id = ?";
        try (Connection connection = DBConnection.getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(UPDATE_SQL)) {

            preparedStatement.setString(1, newGrade);
            preparedStatement.setInt(2, studentId);

            int rowsAffected = preparedStatement.executeUpdate(); // CUD operations සඳහා executeUpdate()
            if (rowsAffected > 0) {
                System.out.println("Student ID " + studentId + " updated successfully to grade " + newGrade + ".");
            } else {
                System.out.println("No student found with ID " + studentId + " or no change made.");
            }

        } catch (SQLException e) {
            System.err.println("Error updating student: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

executeUpdate() method එකෙන් return කරන්නේ SQL statement එක මගින් බලපෑ rows ගණනයි. ඒකෙන් අපිට update එක successful ද කියලා දැනගන්න පුළුවන්.

4.4. Delete (Data මකා දැමීම)

Database එකෙන් data මකා දාන්න අපි DELETE SQL statement එකක් පාවිච්චි කරනවා.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class StudentDAO { 
    // ... addStudent, getAllStudents, getStudentById, updateStudentGrade methods මෙතනට උඩින් ...

    public void deleteStudent(int studentId) {
        String DELETE_SQL = "DELETE FROM students WHERE id = ?";
        try (Connection connection = DBConnection.getConnection();
             PreparedStatement preparedStatement = connection.prepareStatement(DELETE_SQL)) {

            preparedStatement.setInt(1, studentId);

            int rowsAffected = preparedStatement.executeUpdate();
            if (rowsAffected > 0) {
                System.out.println("Student ID " + studentId + " deleted successfully.");
            } else {
                System.out.println("No student found with ID " + studentId + ".");
            }

        } catch (SQLException e) {
            System.err.println("Error deleting student: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Delete එකත් update එක වගේම executeUpdate() method එක පාවිච්චි කරනවා.

4.5. ඔක්කොම එකට - Main Application Class එකක්

අපි හදපු methods ටික පාවිච්චි කරලා CRUD Operations කරලා බලමු. මේක MainApp කියලා class එකක් ඇතුලේ තියමු.

public class MainApp {
    public static void main(String[] args) {
        StudentDAO dao = new StudentDAO();

        // Create Operation
        System.out.println("\n=== Performing Create Operation ===");
        dao.addStudent("Nimal Perera", 20, "Grade A");
        dao.addStudent("Kamala Silva", 22, "Grade B");
        dao.addStudent("Sunil Fernando", 19, "Grade A");

        // Read Operation (All Students)
        System.out.println("\n=== Performing Read Operation (All) ===");
        dao.getAllStudents();

        // Read Operation (by ID)
        System.out.println("\n=== Performing Read Operation (by ID) ===");
        dao.getStudentById(2); // Kamala Silva
        dao.getStudentById(99); // Not existing

        // Update Operation
        System.out.println("\n=== Performing Update Operation ===");
        dao.updateStudentGrade(1, "Grade C"); // Nimal Perera's grade to C
        dao.getAllStudents();

        // Delete Operation
        System.out.println("\n=== Performing Delete Operation ===");
        dao.deleteStudent(3); // Sunil Fernando
        dao.getAllStudents();

        // Try to delete a non-existent student
        dao.deleteStudent(99);
    }
}

මේ MainApp class එක run කලාම, console එකේදී ඔබට database operations වල results ටික බලාගන්න පුළුවන්. නියම වැඩක් නේද? අපි අපේ අත්වලින්ම database එකක් එක්ක CRUD Operations කරා.

අවසානය

හරි යාළුවනේ, මේ guide එකෙන් අපි Java වල JDBC පාවිච්චි කරලා database එකක් එක්ක CRUD Operations කරන හැටි මුල ඉඳන්ම ඉගෙනගත්තා. අපි මුලින්ම JDBC කියන්නේ මොකක්ද කියලා තේරුම් ගත්තා, database එකක් setup කරගෙන, project එකට driver එකක් add කරගත්තා.

ඊට පස්සේ, database connection එකක් හදාගන්න හැටි සහ ඒක ආරක්ෂිතව වහලා දාන හැටිත් බැලුවා. අන්තිමට, PreparedStatement වගේ හොඳම practices පාවිච්චි කරලා, Create, Read, Update, Delete කියන operations ටික හරියටම implement කලේ කොහොමද කියලා අපි code එක්කම දැක්කා.

මතක තියාගන්න, JDBC කියන්නේ Java application එකක database layer එක හදන්න තියෙන fundamental tool එකක්. මේ දැනුම ඔබට Spring Boot වගේ framework එකක් එක්ක වැඩ කරනකොටත් ගොඩක් ප්‍රයෝජනවත් වෙයි, මොකද ඒ frameworks යටින් මේ JDBC concepts තමයි වැඩ කරන්නේ.

ඔබේම project එකක මේවා apply කරලා බලන්න! මොකක් හරි ගැටලුවක් ආවොත්, නැත්නම් මේ ගැන තව මොනවා හරි දැනගන්න ඕනේ නම්, පහළින් comment කරන්න. අපි එකතු වෙලා විසඳුම් හොයාගමු! තවත් මේ වගේම වැදගත් tutorial එකකින් හමුවෙමු!