# 12. Connect Database & mẫu CRUD & switch Oracle/MSSQL

### 12.Quy định kết nối Database và Message Queue

### 12.1. Mục tiêu chương

<div id="bkmrk-">  
</div>Chuẩn hóa kết nối DB và Message Queue nhằm:

- Tránh hardcode cấu hình
- Đảm bảo tính ổn định hạ tầng
- Kiểm soát tài nguyên hệ thống

### 12.2. Khái niệm / phạm vi áp dụng

<div id="bkmrk--1">  
</div>Áp dụng cho:

- Database
- RabbitMQ
- Kafka
- Core Team và Partner

### 12.3. Quy định chính

#### Kết nối Database

Cấu hình datasource tại:  
  
config/\*\*

application-\*.yml

- 
- Không hardcode:
- host
- port
- user
- password

- Không tạo JDBC connection thủ công
- Mọi truy cập DB qua repository/service

---

#### Message Queue

- Kết nối queue do Core Team quản lý

Cấu hình tại:  
  
config/\*\*

common/messaging/\*\*

- 

Partner không được:

- Tự tạo connection
- Hardcode config
- Tự tạo queue/topic

---

#### Chuẩn đặt tên queue/topic

&lt;system&gt;.&lt;module&gt;.&lt;purpose&gt;

Ví dụ:

core.audit.log

planning.project.created

auth.user.synced

### 12.4. Quy trình tạo queue/topic

<div id="bkmrk--7">  
</div>Tạo ticket:  
  
\[QUEUE REQUEST\] &lt;module&gt; - &lt;purpose&gt;

1. 
2. Cung cấp:
- module
- mục đích
- producer
- consumer
- retry/DLQ


**Core tạo queue và cấp quyền**

### 12.5. Checklist DB &amp; Queue

<div id="bkmrk--8">  
</div>Database:

- Không hardcode kết nối
- Có migration khi đổi DB

Queue:

- Queue do Core cấp
- Có log và retry/DLQ

### 13.1. Mục tiêu chương

<div id="bkmrk--2">  
</div>Thiết kế kiến trúc đa database nhằm:

- Tách logic nghiệp vụ và truy vấn
- Switch Oracle/MSSQL bằng cấu hình
- Không sửa service khi đổi DB
- Áp dụng nguyên tắc SOLID

### 13.2. Khái niệm / phạm vi áp dụng

<div id="bkmrk--6">  
</div>Áp dụng cho:

- Các module hỗ trợ đa DB
- Các hệ thống cần deploy trên:
- Oracle
- SQL Server


### 13.3. Quy định chính

<div id="bkmrk--9">  
</div>#### Nguyên tắc thiết kế

- Service không phụ thuộc DB
- Query tách theo dialect:
- Oracle
- MSSQL

- Repository chỉ thực thi SQL
- Switch DB bằng config:

db.vendor = oracle | mssql

---

#### Cấu trúc khuyến nghị

modules/&lt;module&gt;/

 controller/

 service/

 repository/

 query/

 QueryProvider.java

 OracleQueryProvider.java

 SqlServerQueryProvider.java

 entity/

 dto/

---

#### Quy định đa DB

- Không viết SQL trong Service/Controller
- Không if/else theo DB trong Service
- Khác biệt DB chỉ nằm ở QueryProvider
- Dùng named parameters: :param

### 13.4. Cách thực hiện / quy trình

#### Khi thay đổi nghiệp vụ

1. Sửa Service
2. Cập nhật query tương ứng trong provider

---

#### Khi khác DB

1. Chỉ sửa query trong:
- OracleQueryProvider
- SqlServerQueryProvider

3. Không sửa Service

---

#### Khi tạo Pull Request

PR phải:

- Ghi rõ ảnh hưởng
- Có smoke test trên env tương ứng

### 13.5. Ví dụ minh họa

#### Cấu hình

db.vendor = mssql

Hệ thống tự inject:

SqlServerQueryProvider

[![image.png](https://docs.lifetex.vn/uploads/images/gallery/2026-02/scaled-1680-/IaDimage-png.png)](https://docs.lifetex.vn/uploads/images/gallery/2026-02/scaled-1680-/IaDimage-png.png)

---

#### Ví dụ sai

if (dbType.equals("oracle")) {

 // SQL

} else {

 // SQL

}

Sai vì logic DB nằm trong Service.

---

#### Ví dụ đúng

Service:

queryProvider.getFindAllPlanningSql();

QueryProvider quyết định SQL theo DB.

### 13.6. Checklist áp dụng

<div id="bkmrk--34">  
</div>- Service không chứa SQL
- Không if/else theo DB trong service
- SQL nằm trong QueryProvider
- Query dùng named parameters
- PR có test trên DB tương ứng