MongoDB Java 驅動基礎設置
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
3.12.14 <!-- 3.x 系列,4.x+ API 不同 -->
</dependency>
連接配置最佳實踐
public class MongoConfig {
public static MongoClient createClient() {
// 種子節點列表 (生產環境至少 3 個)
List seeds = Arrays.asList(
new ServerAddress("192.168.1.10", 27017),
new ServerAddress("192.168.1.11", 27017)
);
// 認證憑證
List creds = Collections.singletonList(
MongoCredential.createCredential("appUser", "myDB", "password".toCharArray())
);
// 連接池與超時調優
MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(100) // 每主機最大連接數
.threadsAllowedToBlockForConnectionMultiplier(50) // 等待線程倍數
.maxWaitTime(120_000) // 獲取連接最大等待 2分鐘
.connectTimeout(10_000) // 建立連接超時 10秒
.socketTimeout(60_000) // Socket 讀寫超時 60秒
.build();
return new MongoClient(seeds, creds, options);
}
}
模糊查詢:正則表達式四大模式
MongoDB 使用 Pattern (java.util.regex) 實現類 SQL LIKE:
| 模式 | 正則語法 | Java 代碼 | 相當於 SQL |
| 精確匹配 | ^value$ | Pattern.compile("^name$", Pattern.CASE_INSENSITIVE) | WHERE name = 'name' |
| 前綴匹配 (右匹配) | ^prefix.* | Pattern.compile("^name.*", Pattern.CASE_INSENSITIVE) | WHERE name LIKE 'name%' |
| 後綴匹配 (左匹配) | .*suffix$ | Pattern.compile("^.*name$", Pattern.CASE_INSENSITIVE) | WHERE name LIKE '%name' |
| 包含匹配 (模糊) | .*substr.* | Pattern.compile("^.*name.*$", Pattern.CASE_INSENSITIVE) | WHERE name LIKE '%name%' |
完整查詢代碼
public List fuzzyQuery(MongoDatabase db, String collection, String field, String keyword, int limit) {
// 1. 構建不區分大小寫的包含匹配正則
Pattern pattern = Pattern.compile(".*" + Pattern.quote(keyword) + ".*", Pattern.CASE_INSENSITIVE);
// 2. 查詢條件
Bson filter = Filters.regex(field, pattern);
// 3. 排序 (可選)
Bson sort = Sorts.ascending(field); // 1=升序, -1=降序
// 4. 執行查詢
return db.getCollection(collection)
.find(filter)
.sort(sort)
.limit(limit)
.into(new ArrayList<>());
}
分頁查詢:skip + limit
public List paginateQuery(MongoDatabase db, String collection, Bson filter,
Bson sort, int pageNum, int pageSize, Class clazz) {
// 參數校驗
if (pageNum < 1) pageNum = 1;
if (pageSize < 1) pageSize = 20;
if (pageSize > 100) pageSize = 100; // 防止過大
long skip = (long)(pageNum - 1) * pageSize;
return db.getCollection(collection)
.find(filter)
.sort(sort)
.skip(skip)
.limit(pageSize)
.map(doc -> MongoUtils.fromDocument(doc, clazz)) // 自定義文檔轉對象
.into(new ArrayList<>());
}
// 獲取總數 (用於前端分頁組件)
public long countTotal(MongoDatabase db, String collection, Bson filter) {
return db.getCollection(collection).countDocuments(filter);
}
綜合實戰:用戶查詢服務
@Service
public class UserQueryService {
private final MongoDatabase db;
public UserQueryService(MongoClient client) {
this.db = client.getDatabase("business_db");
}
public PageResult searchUsers(String keyword, int page, int size) {
// 1. 構建過濾器
Bson filter = Filters.and(
Filters.eq("status", 1), // 只查啟用用戶
keyword != null ? Filters.or(
Filters.regex("username", Pattern.compile(".*" + Pattern.quote(keyword) + ".*", Pattern.CASE_INSENSITIVE)),
Filters.regex("email", Pattern.compile(".*" + Pattern.quote(keyword) + ".*", Pattern.CASE_INSENSITIVE)),
Filters.regex("phone", Pattern.compile(".*" + Pattern.quote(keyword) + ".*"))
) : new Document()
);
// 2. 總數
long total = db.getCollection("users").countDocuments(filter);
// 3. 分頁數據
List data = paginateQuery(db, "users", filter,
Sorts.descending("createTime"), page, size, UserDTO.class);
return new PageResult<>(page, size, total, data);
}
}
性能優化關鍵點
- 建立索引:模糊查詢字段 (username/email/phone) 必須建立文本索引或普通索引,否則全表掃描極慢。
db.users.createIndex({username: "text", email: "text", phone: "text"}) (文本索引支援更豐富搜索)
- 避免深分頁:
skip(100000) 性能極差。大數據量請用游標分頁 (記住上一頁最後一個 _id,查詢 {_id: {$gt: lastId}})。
- 投影字段:只查需要的字段
.projection(fields(include("username", "email"), excludeId())),減少網絡傳輸。
- 連接池監控:監控
connectionsInUse、waitQueueSize,及時擴容。
避坑指南
| 坑點 | 後果 | 解決 |
| 正則未用 Pattern.quote | 關鍵字含特殊字符 (.,*,?,+,...) 導致匹配錯誤或注入 | 必須 Pattern.quote(keyword) 轉義 |
| 大小寫敏感 | 漏查數據 | 加 Pattern.CASE_INSENSITIVE 標誌 |
| skip 過大 | 查詢超時、CPU 飆升 | 改用游標分頁、或限制最大頁碼 |
| 未關閉游標 | 連接洩漏、內存溢出 | 用 try-with-resources 或 .into(list) 自動關閉 |
- 上一篇文章: FreeMarker 入門:最簡單模板引擎示例詳解
- 下一篇文章: Java 集合框架核心:Map 與 Collection 體系深度解析
Copyright ©
程式碼之家 All Rights Reserved