admin
  •  admin
  • Advanced Member Topic Starter
2024-09-12T02:41:43Z
Tài liệu tự học: JDBC Kết nối trong dự án Java Maven với SQLite

Mục lục:

Giới thiệu về JDBC và SQLite
Hướng dẫn cài đặt và thiết lập Maven
Cài đặt thư viện JDBC
Kết nối với cơ sở dữ liệu SQLite
Thực hiện các truy vấn SQL và lấy kết quả
Parse query và tạo ArrayList object

1. Giới thiệu về JDBC và SQLite

JDBC (Java Database Connectivity) là một API trong Java cho phép các ứng dụng Java kết nối và tương tác với cơ sở dữ liệu. SQLite là một hệ quản trị cơ sở dữ liệu quan hệ nhẹ và phổ biến được sử dụng trong các ứng dụng nhỏ và nhẹ.
2. Hướng dẫn cài đặt và thiết lập Maven

Maven là một công cụ quản lý dự án phổ biến trong lập trình Java. Để tạo dự án Maven, làm theo các bước sau:

Bước 1: Cài đặt Maven từ trang chủ của Apache Maven (https://maven.apache.org/). Bước 2: Thiết lập biến môi trường MAVEN_HOME và thêm %MAVEN_HOME%\bin vào biến môi trường PATH. Bước 3: Kiểm tra cài đặt bằng cách chạy lệnh mvn -version trong dòng lệnh.
3. Cài đặt thư viện JDBC

Để sử dụng JDBC để kết nối với cơ sở dữ liệu SQLite, chúng ta cần thêm thư viện JDBC vào dự án Maven. Thêm đoạn mã sau vào tệp pom.xml của dự án:

<dependencies>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.34.0</version>
</dependency>
</dependencies>

Sau khi thêm phần dependency, Maven sẽ tải xuống và cài đặt thư viện JDBC cho dự án của bạn.
4. Kết nối với cơ sở dữ liệu SQLite

Sau khi đã cài đặt thư viện JDBC, chúng ta có thể kết nối với cơ sở dữ liệu SQLite bằng cách sử dụng đoạn mã sau:

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

public class SQLiteConnection {
public static void main(String[] args) {
Connection connection = null;
try {
// Kết nối với cơ sở dữ liệu SQLite
connection = DriverManager.getConnection("jdbc:sqlite:path/to/database.db");
System.out.println("Kết nối thành công!");

// Thực hiện các truy vấn và tương tác với cơ sở dữ liệu ở đây

} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}
}

Trong đoạn mã trên, "path/to/database.db" là đường dẫn tới tệp SQLite database.
5. Thực hiện các truy vấn SQL và lấy kết quả

Để thực hiện các truy vấn SQL và lấy kết quả từ cơ sở dữ liệu SQLite, chúng ta có thể sử dụng đối tượng Statement hoặc PreparedStatement. Dưới đây là một ví dụ minh họa:

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

public class SQLiteQuery {
public static void main(String[] args) {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:sqlite:path/to/database.db");
System.out.println("Kết nối thành công!");

Statement statement = connection.createStatement();
String query = "SELECT * FROM table_name";
ResultSet resultSet = statement.executeQuery(query);

while (resultSet.next()) {
// Xử lý kết quả từ ResultSet ở đây
}

} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}
}

Trong ví dụ trên, SELECT * FROM table_name là một truy vấn SQL đơn giản để lấy tất cả các hàng từ bảng table_name. Bạn có thể thay đổi truy vấn theo nhu cầu của mình.
6. Parse query và tạo ArrayList object

Để parse query và tạo một ArrayList object từ kết quả truy vấn, bạn cần định nghĩa một lớp đại diện cho đối tượng trong bảng. Dưới đây là một ví dụ minh họa:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class SQLiteQuery {
public static void main(String[] args) {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:sqlite:path/to/database.db");
System.out.println("Kết nối thành công!");

Statement statement = connection.createStatement();
String query = "SELECT * FROM table_name";
ResultSet resultSet = statement.executeQuery(query);

List<YourObject> resultList = new ArrayList<>();

while (resultSet.next()) {
YourObject obj = new YourObject();
obj.setId(resultSet.getInt("id"));
obj.setName(resultSet.getString("name"));
// Đặt các trường khác vào đối tượng obj

resultList.add(obj);
}

// Sử dụng resultList ở đây

} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}
}

Trong ví dụ trên, YourObject là lớp đại diện cho đối tượng trong bảng. Bạn cần định nghĩa các trường và phương thức getter/setter tương ứng cho các trường đó. Trong vòng lặp, ta tạo một đối tượng YourObject, đọc các giá trị từ ResultSet và đặt vào đối tượng, sau đó thêm đối tượng vào resultList.

Sau khi kết thúc vòng lặp, bạn có thể sử dụng resultList để làm việc với dữ liệu trả về từ cơ sở dữ liệu.
6. Thực hiện truy vấn Execute

Để thực hiện một truy vấn SQL bằng JDBC mà không cần kết quả trả về, chẳng hạn như INSERT, UPDATE hoặc DELETE, bạn có thể sử dụng phương thức executeUpdate() của đối tượng Statement hoặc PreparedStatement. Dưới đây là một ví dụ minh họa:

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

public class SQLiteUpdate {
public static void main(String[] args) {
Connection connection = null;
try {
connection = DriverManager.getConnection("jdbc:sqlite:path/to/database.db");
System.out.println("Kết nối thành công!");

Statement statement = connection.createStatement();
String query = "INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2')";
int rowsAffected = statement.executeUpdate(query);

System.out.println("Số hàng bị ảnh hưởng: " + rowsAffected);

} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
try {
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}
}

Trong ví dụ trên, INSERT INTO table_name (column1, column2) VALUES ('value1', 'value2') là một truy vấn INSERT SQL đơn giản để chèn dữ liệu vào bảng table_name. Bạn có thể thay đổi truy vấn theo nhu cầu của mình.

Phương thức executeUpdate() trả về số hàng bị ảnh hưởng bởi truy vấn. Trong ví dụ trên, chúng ta sử dụng biến rowsAffected để lưu giá trị này và in ra số hàng bị ảnh hưởng.

Lưu ý rằng khi sử dụng truy vấn INSERT, UPDATE hoặc DELETE, bạn nên sử dụng PreparedStatement thay vì Statement để tránh các vấn đề bảo mật và các vấn đề liên quan đến SQL Injection.

Đó là cách thực hiện một truy vấn SQL mà không cần kết quả trả về trong JDBC. Bạn có thể áp dụng tương tự cho các truy vấn SQL khác mà không cần lấy dữ liệu trả về từ cơ sở dữ liệu.
7. Thực hiện truy vấn với Store Procedure

Để sử dụng JDBC để gọi một stored procedure và truyền tham số vào procedure, bạn có thể sử dụng đối tượng CallableStatement trong JDBC. Dưới đây là một ví dụ minh họa:

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

public class CallStoredProcedure {
public static void main(String[] args) {
Connection connection = null;
CallableStatement callableStatement = null;

try {
connection = DriverManager.getConnection("jdbc:sqlite:path/to/database.db");
System.out.println("Kết nối thành công!");

// Tạo một CallableStatement để gọi stored procedure
callableStatement = connection.prepareCall("{call procedure_name(?, ?)}");

// Đặt giá trị các tham số vào stored procedure
callableStatement.setString(1, "value1");
callableStatement.setInt(2, 123);

// Thực thi stored procedure
callableStatement.execute();

System.out.println("Stored procedure đã được gọi thành công!");

} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
try {
if (callableStatement != null)
callableStatement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}
}
}

Trong ví dụ trên, procedure_name là tên của stored procedure mà bạn muốn gọi. Bạn nên thay thế procedure_name bằng tên thực tế của stored procedure trong cơ sở dữ liệu của bạn.

callableStatement = connection.prepareCall("{call procedure_name(?, ?)}"); dùng để tạo một đối tượng CallableStatement để gọi stored procedure. Trong truy vấn này, chúng ta sử dụng ? để đại diện cho các tham số của stored procedure.

callableStatement.setString(1, "value1"); và callableStatement.setInt(2, 123); được sử dụng để đặt giá trị cho các tham số của stored procedure. Trong ví dụ này, chúng ta đặt giá trị chuỗi "value1" cho tham số đầu tiên và giá trị số 123 cho tham số thứ hai. Bạn nên thay đổi các giá trị này tùy thuộc vào yêu cầu của stored procedure của bạn.

Cuối cùng, callableStatement.execute(); được sử dụng để thực thi stored procedure. Bạn cũng có thể sử dụng các phương thức khác như executeQuery() hoặc executeUpdate() tùy thuộc vào kiểu kết quả mà stored procedure trả về.
EXTRA: Viết hàm dùng chung để tương tác với lớp trừu tượng Generic

Nếu bạn muốn tự động lặp qua các cột của ResultSet và gán giá trị cho các trường có tên tương đương trong lớp đại diện T, bạn có thể sử dụng đối tượng ResultSetMetaData để thu thập thông tin về các cột và sử dụng reflection để gán giá trị. Dưới đây là một cách giải quyết:

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;

public class DBHelper {
private static final String DB_URL = "jdbc:sqlite:path/to/database.db";

public static <T> ArrayList<T> executeQuery(String query, Class<T> clazz) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
ArrayList<T> results = new ArrayList<>();

try {
connection = DriverManager.getConnection(DB_URL);
statement = connection.createStatement();
resultSet = statement.executeQuery(query);

ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();

while (resultSet.next()) {
T result = clazz.getDeclaredConstructor().newInstance();

for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnName(i);
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);
field.set(result, resultSet.getObject(i));
}

results.add(result);
}

} catch (SQLException | ReflectiveOperationException e) {
System.err.println(e.getMessage());
} finally {
try {
if (resultSet != null)
resultSet.close();
if (statement != null)
statement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
System.err.println(e);
}
}

return results;
}
}

Trong ví dụ trên, phương thức executeQuery nhận một truy vấn SQL và một đối tượng Class clazz, đại diện cho lớp mô hình (model) bạn muốn truy vấn trả về.

Trong phần thân của phương thức executeQuery, chúng ta thu thập thông tin về cột bằng cách sử dụng ResultSetMetaData. Chúng ta lặp qua từng hàng của ResultSet và tạo một đối tượng mới của T sử dụng clazz.getDeclaredConstructor().newInstance().

Sau đó, chúng ta lặp qua từng cột của hàng hiện tại và lấy tên cột sử dụng metaData.getColumnName(i). Chúng ta sử dụng clazz.getDeclaredField(columnName) để lấy trường tương ứng trong lớp T. Sau đó, chúng ta gán giá trị của cột sử dụng field.set(result, resultSet.getObject(i)).

Cuối cùng, chúng ta thêm đối tượng result vào danh sách kết quả.

Để sử dụng phương thức executeQuery, bạn có thể truyền truy vấn SQL và lớp mô hình (model) như sau:

public class User {
private int id;
private String name;
// ... các trường khác và phương thức getter/setter

public static void main(String[] args) {
String query = "SELECT id, name FROM users";
ArrayList<User> users = DBHelper.executeQuery(query, User.class);

// Sử dụng danh sách người dùng đã truy vấn
for (User user : users) {
System.out.println(user.getId() + " - " + user.getName());
}
}
}

Trong ví dụ trên, chúng ta sử dụng lớp User làm mô hình (model) và truyền User.class vào phương thức executeQuery.

Lưu ý rằng cách này giả định rằng tên cột trong ResultSet tương ứng với tên của các trường trong lớp mô hình (model). Nếu có sự khác biệt trong tên, bạn có thể sử dụng các chú thích hoặc quy ước tên để ánh xạ đúng giữa cột và trường.
9: Hibernate

Hibernate là một framework ORM (Object-Relational Mapping) trong Java, được sử dụng để ánh xạ các đối tượng Java vào cơ sở dữ liệu quan hệ. Nó cung cấp một cách tiện lợi và mạnh mẽ để làm việc với cơ sở dữ liệu mà không cần viết trực tiếp các truy vấn SQL.

Một số lợi ích chính khi sử dụng Hibernate là:

Giảm thiểu mã lặp: Hibernate giúp giảm thiểu mã lặp bằng cách tự động xử lý các phần tử của lớp đối tượng và ánh xạ chúng vào cơ sở dữ liệu. Bạn không cần phải viết các truy vấn SQL chi tiết và quản lý kết nối cơ sở dữ liệu một cách rõ ràng.

Tính di động của cơ sở dữ liệu: Hibernate cho phép bạn thay đổi cơ sở dữ liệu mà không cần sửa đổi mã nguồn của ứng dụng. Bạn có thể chuyển đổi giữa các cơ sở dữ liệu quan hệ như MySQL, Oracle, PostgreSQL một cách dễ dàng.

Tối ưu hiệu suất: Hibernate cung cấp các cơ chế tối ưu hiệu suất như lazy loading (tải lười) và caching (bộ đệm). Lazy loading cho phép tải dữ liệu từ cơ sở dữ liệu theo yêu cầu, giúp giảm thiểu lượng dữ liệu không cần thiết được tải vào bộ nhớ. Caching giúp lưu trữ các dữ liệu truy vấn phổ biến trong bộ nhớ để truy cập nhanh hơn và giảm tải cho cơ sở dữ liệu.

Đảm bảo tính nhất quán dữ liệu: Hibernate hỗ trợ các giao dịch (transactions) để đảm bảo tính nhất quán dữ liệu trong ứng dụng. Bạn có thể sử dụng các phương thức như beginTransaction(), commit() và rollback() để quản lý các thay đổi dữ liệu.

Tích hợp dễ dàng: Hibernate tích hợp tốt với các framework và công nghệ phổ biến khác trong cộng đồng Java như Spring, Java EE và JPA (Java Persistence API). Điều này giúp bạn xây dựng ứng dụng linh hoạt và dễ dàng mở rộng.

Tính bảo mật: Hibernate cung cấp các công cụ và cơ chế bảo mật để bảo vệ dữ liệu trong cơ sở dữ liệu. Bạn có thể áp dụng các quyền truy cập và ràng buộc dữ liệu thông qua các annotation và cấu hình.

Tổng quan, Hibernate giúp giảm thiểu công việc lặp lại, tăng tính di động, cải thiện hiệu suất và đảm bảo tính nhất quán dữ liệu. Nó là một công cụ quan trọng trong phát triển ứng dụng Java liên quan đến cơ sở dữ liệu.

Để tạo một dự án Java sử dụng Maven và tích hợp Hibernate với cơ sở dữ liệu SQLite, bạn có thể làm theo các bước sau:

Bước 1: Tạo dự án Maven

Mở trình quản lý dự án hoặc dòng lệnh, đảm bảo rằng Maven đã được cài đặt trên hệ thống của bạn.
Tạo một thư mục mới cho dự án của bạn và di chuyển vào thư mục đó.
Khởi tạo dự án Maven bằng lệnh sau:

mvn archetype:generate -DgroupId=com.example -DartifactId=myproject -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Trong lệnh trên, thay thế com.example bằng groupId của bạn và myproject bằng artifactId của dự án.

Bước 2: Thêm dependency Hibernate vào dự án Maven

Mở tệp pom.xml trong dự án của bạn.
Thêm dependency Hibernate vào phần <dependencies> như sau:

<dependencies>
<!-- Các dependency khác -->

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.34.0</version>
</dependency>
</dependencies>

Trong ví dụ trên, chúng ta đã thêm dependency Hibernate Core, Hibernate EntityManager và SQLite JDBC.

Bước 3: Cấu hình Hibernate và SQLite

Tạo một tệp cấu hình Hibernate (ví dụ: hibernate.cfg.xml) trong thư mục src/main/resources của dự án.
Đặt thông tin kết nối SQLite trong tệp cấu hình như sau:

<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.SQLiteDialect</property>
<property name="hibernate.connection.driver_class">org.sqlite.JDBC</property>
<property name="hibernate.connection.url">jdbc:sqlite:/path/to/database.db</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- Các cấu hình khác -->
</session-factory>
</hibernate-configuration>

Chú ý thay thế /path/to/database.db bằng đường dẫn tới tệp cơ sở dữ liệu SQLite của bạn.

Bước 4: Định nghĩa lớp mô hình (model)

Tạo một thư mục src/main/java trong dự án của bạn (nếu nó chưa tồn tại).
Trong thư mục src/main/java, tạo các package và lớp Java để đại diện cho mô hình dữ liệu của bạn. Ví dụ, tạo package com.example.model và lớp User trong package đó.

package com.example.model;

import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@Column(name = "name")
private String name;

// Các trường và phương thức getter/setter khác
}

Bước 5: Sử dụng Hibernate để thực hiện ORM

Tạo một lớp Java (ví dụ: Main.java) trong thư mục src/main/java để chạy chương trình.
Trong lướp Main.java, bạn có thể sử dụng Hibernate API để thực hiện các hoạt động ORM. Dưới đây là một ví dụ đơn giản:

package com.example;

import com.example.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Main {
public static void main(String[] args) {
// Khởi tạo SessionFactory từ cấu hình
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();

// Tạo phiên làm việc
Session session = sessionFactory.openSession();
session.beginTransaction();

// Thực hiện các hoạt động ORM
User user = new User();
user.setName("John Doe");
session.save(user);

// Đóng phiên làm việc
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}

Trong ví dụ trên, chúng ta đã khởi tạo SessionFactory từ cấu hình Hibernate được định nghĩa trong tệp hibernate.cfg.xml. Sau đó, chúng ta mở một phiên làm việc (Session), bắt đầu một giao dịch, thêm một đối tượng User vào cơ sở dữ liệu thông qua session.save(), hoàn tất giao dịch và đóng phiên làm việc và SessionFactory.
Privacy Policy | 2.31.16
Thời gian xử lý trang này hết 0,476 giây.