C# SQLite基本使用示例

目錄

1?基本使用流程

1.1 步驟1:添加SQLite依賴

1.2 ?步驟2:建立連接

1.3 步驟3:執行SQL命令

1.4 步驟4:查詢數據

1.5 步驟5:使用事務

2 SQLite基本使用示例

2.1 準備工作

2.2 完整示例

2.3 案例代碼解析

2.3.1 連接管理

2.3.2 執行非查詢命令

2.3.3 參數化查詢

2.3.4 使用事務

2.3.5 查詢和結果處理


本節將通過代碼示例展示如何在C#中使用SQLite數據庫。這個示例包含了創建連接、創建表、執行CRUD操作、事務處理和使用參數化查詢等基本功能。在C#應用程序中使用SQLite是一個常見的需求,特別是對于需要輕量級數據存儲的應用,將詳細總結C#中使用SQLite數據庫的基本流程,并解釋案例中的代碼含義和一些重要注意事項。

1?基本使用流程

1.1 步驟1:添加SQLite依賴

在C#項目中使用SQLite,首先需要添加適當的NuGet包:

System.Data.SQLite (完整版)
或
Microsoft.Data.Sqlite (輕量版,.NET Core/.NET 5+推薦)

通過Visual Studio的NuGet包管理器或命令行添加:

Install-Package System.Data.SQLite

dotnet add package Microsoft.Data.Sqlite

1.2 ?步驟2:建立連接

// 引入命名空間
using System.Data.SQLite;
?
// 連接字符串
string connectionString = "Data Source=database.db;Version=3;";
?
// 創建連接
using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{connection.Open();// 執行數據庫操作...// 使用using語句確保連接被正確關閉
}

1.3 步驟3:執行SQL命令

// 執行非查詢命令(DDL或DML)
using (SQLiteCommand command = new SQLiteCommand(connection))
{command.CommandText = "CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY, Name TEXT, Email TEXT)";command.ExecuteNonQuery();
}
?
// 插入數據
using (SQLiteCommand command = new SQLiteCommand(connection))
{command.CommandText = "INSERT INTO Users (Name, Email) VALUES (@Name, @Email)";command.Parameters.AddWithValue("@Name", "張三");command.Parameters.AddWithValue("@Email", "zhangsan@example.com");command.ExecuteNonQuery();
}

1.4 步驟4:查詢數據

// 查詢數據
using (SQLiteCommand command = new SQLiteCommand("SELECT * FROM Users", connection))
{using (SQLiteDataReader reader = command.ExecuteReader()){while (reader.Read()){int id = reader.GetInt32(0);string name = reader.GetString(1);string email = reader.GetString(2);Console.WriteLine($"ID: {id}, Name: {name}, Email: {email}");}}
}

1.5 步驟5:使用事務

using (SQLiteConnection connection = new SQLiteConnection(connectionString))
{connection.Open();using (SQLiteTransaction transaction = connection.BeginTransaction()){try{// 執行多個數據庫操作using (SQLiteCommand command = new SQLiteCommand(connection, transaction)){command.CommandText = "INSERT INTO Users (Name) VALUES (@Name)";command.Parameters.AddWithValue("@Name", "李四");command.ExecuteNonQuery();command.CommandText = "UPDATE Users SET Email = @Email WHERE Name = @Name";command.Parameters.AddWithValue("@Email", "lisi@example.com");command.Parameters.AddWithValue("@Name", "李四");command.ExecuteNonQuery();}// 如果一切正常,提交事務transaction.Commit();}catch (Exception ex){// 發生錯誤,回滾事務transaction.Rollback();Console.WriteLine($"事務回滾: {ex.Message}");}}
}

2 SQLite基本使用示例

2.1 準備工作

首先,你需要安裝SQLite的C#驅動。在Visual Studio中,通過NuGet包管理器安裝System.Data.SQLiteMicrosoft.Data.Sqlite

// 使用NuGet包管理器控制臺安裝
// Install-Package System.Data.SQLite
// 或者
// Install-Package Microsoft.Data.Sqlite

2.2 完整示例

using System;
using System.Data.SQLite; // 使用System.Data.SQLite包
using System.IO;namespace SQLiteDemo
{class Program{// 數據庫連接字符串private static string dbFile = "mydatabase.db";private static string connectionString = $"Data Source={dbFile};Version=3;";static void Main(string[] args){try{// 確保數據庫文件存在,如果不存在則創建CreateDatabaseIfNotExists();// 創建表CreateTables();// 插入數據InsertData();// 查詢數據QueryData();// 更新數據UpdateData();// 使用事務批量插入BatchInsertWithTransaction();// 刪除數據DeleteData();// 參數化查詢示例ParameterizedQueryExample();Console.WriteLine("所有操作已完成!");}catch (Exception ex){Console.WriteLine($"發生錯誤: {ex.Message}");Console.WriteLine(ex.StackTrace);}Console.ReadKey();}// 創建數據庫文件static void CreateDatabaseIfNotExists(){if (!File.Exists(dbFile)){Console.WriteLine("創建新的數據庫文件...");SQLiteConnection.CreateFile(dbFile);Console.WriteLine("數據庫文件已創建。");}else{Console.WriteLine("使用現有數據庫文件。");}}// 創建表static void CreateTables(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();Console.WriteLine("已連接到數據庫。");// 創建用戶表string createUserTableSql = @"CREATE TABLE IF NOT EXISTS Users (Id INTEGER PRIMARY KEY AUTOINCREMENT,Name TEXT NOT NULL,Email TEXT UNIQUE,Age INTEGER,RegisterDate TEXT DEFAULT CURRENT_TIMESTAMP)";// 創建訂單表,演示外鍵關系string createOrderTableSql = @"CREATE TABLE IF NOT EXISTS Orders (OrderId INTEGER PRIMARY KEY AUTOINCREMENT,UserId INTEGER,ProductName TEXT NOT NULL,Quantity INTEGER DEFAULT 1,OrderDate TEXT DEFAULT CURRENT_TIMESTAMP,FOREIGN KEY (UserId) REFERENCES Users(Id))";using (var command = new SQLiteCommand(createUserTableSql, connection)){command.ExecuteNonQuery();Console.WriteLine("Users表已創建。");}using (var command = new SQLiteCommand(createOrderTableSql, connection)){command.ExecuteNonQuery();Console.WriteLine("Orders表已創建。");}}}// 插入數據static void InsertData(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 插入用戶數據string insertUserSql = @"INSERT INTO Users (Name, Email, Age) VALUES (@Name, @Email, @Age)";using (var command = new SQLiteCommand(insertUserSql, connection)){// 添加參數command.Parameters.AddWithValue("@Name", "張三");command.Parameters.AddWithValue("@Email", "zhangsan@example.com");command.Parameters.AddWithValue("@Age", 28);int rowsAffected = command.ExecuteNonQuery();Console.WriteLine($"插入了 {rowsAffected} 行用戶數據。");// 獲取自增IDstring getLastIdSql = "SELECT last_insert_rowid()";using (var idCommand = new SQLiteCommand(getLastIdSql, connection)){long userId = (long)idCommand.ExecuteScalar();Console.WriteLine($"新插入用戶的ID是: {userId}");// 為該用戶添加訂單string insertOrderSql = @"INSERT INTO Orders (UserId, ProductName, Quantity)VALUES (@UserId, @ProductName, @Quantity)";using (var orderCommand = new SQLiteCommand(insertOrderSql, connection)){orderCommand.Parameters.AddWithValue("@UserId", userId);orderCommand.Parameters.AddWithValue("@ProductName", "筆記本電腦");orderCommand.Parameters.AddWithValue("@Quantity", 1);rowsAffected = orderCommand.ExecuteNonQuery();Console.WriteLine($"插入了 {rowsAffected} 行訂單數據。");}}}}}// 查詢數據static void QueryData(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 簡單查詢string queryUsersSql = "SELECT * FROM Users";using (var command = new SQLiteCommand(queryUsersSql, connection)){Console.WriteLine("\n所有用戶:");using (var reader = command.ExecuteReader()){while (reader.Read()){Console.WriteLine($"ID: {reader["Id"]}, 姓名: {reader["Name"]}, " +$"郵箱: {reader["Email"]}, 年齡: {reader["Age"]}, " +$"注冊日期: {reader["RegisterDate"]}");}}}// 聯表查詢string queryOrdersSql = @"SELECT o.OrderId, u.Name as UserName, o.ProductName, o.Quantity, o.OrderDateFROM Orders oJOIN Users u ON o.UserId = u.IdORDER BY o.OrderDate DESC";using (var command = new SQLiteCommand(queryOrdersSql, connection)){Console.WriteLine("\n所有訂單:");using (var reader = command.ExecuteReader()){while (reader.Read()){Console.WriteLine($"訂單ID: {reader["OrderId"]}, 用戶: {reader["UserName"]}, " +$"商品: {reader["ProductName"]}, 數量: {reader["Quantity"]}, " +$"訂單日期: {reader["OrderDate"]}");}}}// 聚合查詢string aggregateQuerySql = @"SELECT COUNT(*) as UserCount, AVG(Age) as AvgAgeFROM Users";using (var command = new SQLiteCommand(aggregateQuerySql, connection)){using (var reader = command.ExecuteReader()){if (reader.Read()){Console.WriteLine($"\n統計信息: 用戶總數: {reader["UserCount"]}, 平均年齡: {reader["AvgAge"]}");}}}}}// 更新數據static void UpdateData(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();string updateUserSql = @"UPDATE Users SET Age = @NewAge, Name = @NewNameWHERE Email = @Email";using (var command = new SQLiteCommand(updateUserSql, connection)){command.Parameters.AddWithValue("@NewAge", 29);command.Parameters.AddWithValue("@NewName", "張三(已更新)");command.Parameters.AddWithValue("@Email", "zhangsan@example.com");int rowsAffected = command.ExecuteNonQuery();Console.WriteLine($"\n更新了 {rowsAffected} 行用戶數據。");}}}// 使用事務批量插入static void BatchInsertWithTransaction(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 開始事務using (var transaction = connection.BeginTransaction()){try{string insertUserSql = @"INSERT INTO Users (Name, Email, Age) VALUES (@Name, @Email, @Age)";// 批量插入10個用戶using (var command = new SQLiteCommand(insertUserSql, connection, transaction)){for (int i = 1; i <= 10; i++){command.Parameters.Clear();command.Parameters.AddWithValue("@Name", $"批量用戶{i}");command.Parameters.AddWithValue("@Email", $"user{i}@example.com");command.Parameters.AddWithValue("@Age", 20 + i);command.ExecuteNonQuery();}}// 提交事務transaction.Commit();Console.WriteLine("\n事務批量插入成功,已添加10位用戶。");}catch (Exception ex){// 出錯時回滾事務transaction.Rollback();Console.WriteLine($"\n事務回滾: {ex.Message}");}}}}// 刪除數據static void DeleteData(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 刪除指定用戶string deleteUserSql = "DELETE FROM Users WHERE Name LIKE @NamePattern";using (var command = new SQLiteCommand(deleteUserSql, connection)){command.Parameters.AddWithValue("@NamePattern", "批量用戶%");int rowsAffected = command.ExecuteNonQuery();Console.WriteLine($"\n刪除了 {rowsAffected} 行用戶數據。");}}}// 參數化查詢示例 - 防止SQL注入static void ParameterizedQueryExample(){using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 這是安全的方式,使用參數化查詢string safeQuerySql = "SELECT * FROM Users WHERE Name LIKE @NamePattern";using (var command = new SQLiteCommand(safeQuerySql, connection)){// 即使用戶輸入包含SQL注入嘗試,也會被當作普通字符串處理string userInput = "張三' OR '1'='1";command.Parameters.AddWithValue("@NamePattern", "%" + userInput + "%");Console.WriteLine("\n執行參數化查詢(防止SQL注入):");using (var reader = command.ExecuteReader()){bool hasResults = false;while (reader.Read()){hasResults = true;Console.WriteLine($"ID: {reader["Id"]}, 姓名: {reader["Name"]}");}if (!hasResults){Console.WriteLine("沒有找到匹配的記錄。");}}}// 注意: 這里演示如何使用執行單值查詢string countSql = "SELECT COUNT(*) FROM Users";using (var command = new SQLiteCommand(countSql, connection)){int count = Convert.ToInt32(command.ExecuteScalar());Console.WriteLine($"\n數據庫中共有 {count} 個用戶。");}}}}
}

2.3 案例代碼解析

2.3.1 連接管理

static void SetupExampleData()
{using (var connection = new SQLiteConnection(connectionString)){connection.Open();// 數據庫操作...}
}

解析:

  • using語句確保即使發生異常,連接也會被正確釋放和關閉,避免資源泄漏

  • connection.Open()建立與SQLite數據庫文件的物理連接

  • 連接字符串格式通常為Data Source=文件路徑;Version=3;,其中文件路徑可以是相對或絕對路徑

2.3.2 執行非查詢命令

static void ExecuteNonQuery(SQLiteConnection connection, string sql, SQLiteTransaction transaction = null)
{using (var command = new SQLiteCommand(sql, connection, transaction)){command.ExecuteNonQuery();}
}

解析:

  • 這是一個輔助方法,用于執行不返回結果集的SQL命令(如CREATE, INSERT, UPDATE, DELETE)

  • 參數化設計允許重用并支持事務

  • ExecuteNonQuery()返回受影響的行數(對于DDL語句如CREATE TABLE通常返回0)

  • 同樣使用using語句確保命令資源被正確釋放

2.3.3 參數化查詢

ExecuteNonQuery(connection, @"INSERT INTO Employees (Name, DeptId, Salary, HireDate) VALUES('張三', 1, 15000, '2020-01-15')");

更安全的參數化版本:

using (var command = new SQLiteCommand(connection))
{command.CommandText = "INSERT INTO Employees (Name, DeptId, Salary, HireDate) VALUES (@Name, @DeptId, @Salary, @HireDate)";command.Parameters.AddWithValue("@Name", "張三");command.Parameters.AddWithValue("@DeptId", 1);command.Parameters.AddWithValue("@Salary", 15000);command.Parameters.AddWithValue("@HireDate", "2020-01-15");command.ExecuteNonQuery();
}

解析:

  • 參數化查詢防止SQL注入攻擊

  • 使用@前綴的參數名稱是約定

  • AddWithValue方法會自動根據傳入參數的類型設置SQLite參數類型

2.3.4 使用事務

using (var transaction = connection.BeginTransaction())
{try{// 執行多個操作ExecuteNonQuery(connection, "INSERT INTO Departments (DeptId, Name) VALUES (4, '人力資源部')", transaction);ExecuteNonQuery(connection, "UPDATE Employees SET Salary = Salary * 1.1 WHERE DeptId = 1", transaction);// 假設這里有條件判斷是否提交bool shouldCommit = true;if (shouldCommit){transaction.Commit();Console.WriteLine("事務已提交。");}else{transaction.Rollback();Console.WriteLine("事務已回滾。");}}catch (Exception ex){transaction.Rollback();Console.WriteLine($"發生錯誤,事務已回滾: {ex.Message}");}
}

解析:

  • BeginTransaction()開始一個新事務

  • 事務內的所有操作要么全部成功,要么全部失敗

  • Commit()提交所有更改并結束事務

  • Rollback()撤銷所有更改并結束事務

  • try-catch塊確保在發生異常時事務被正確回滾

2.3.5 查詢和結果處理

static void DisplayQueryResults(SQLiteConnection connection, string sql)
{using (var command = new SQLiteCommand(sql, connection)){using (var reader = command.ExecuteReader()){// 獲取列名List<string> columns = new List<string>();for (int i = 0; i < reader.FieldCount; i++){columns.Add(reader.GetName(i));}// 輸出列名Console.WriteLine(string.Join(" | ", columns));Console.WriteLine(new string('-', columns.Count * 15));// 輸出行while (reader.Read()){List<string> values = new List<string>();for (int i = 0; i < reader.FieldCount; i++){values.Add(reader[i]?.ToString() ?? "NULL");}Console.WriteLine(string.Join(" | ", values));}}}
}

解析:

  • ExecuteReader()返回一個SQLiteDataReader對象,用于逐行讀取結果集

  • reader.FieldCount獲取結果集的列數

  • reader.GetName(i)獲取特定列的名稱

  • reader.Read()將讀取指針移到下一行,如果有下一行則返回true

  • reader[i]獲取當前行中索引為i的列的值

  • ?? "NULL"處理可能的NULL值

  • 嵌套的using語句確保讀取器和命令都被正確關閉

3 數據類型映射

C#類型和SQLite類型之間的映射:

C#類型SQLite類型
int, longINTEGER
double, floatREAL
stringTEXT
byte[]BLOB
DateTimeTEXT/INTEGER
boolINTEGER

在讀取時需要注意類型轉換,SQLite的動態類型系統可能需要額外的類型轉換處理。

4 使用注意事項

  1. 連接管理

    • ?總是使用using語句確保連接正確關閉

    • 避免長時間保持連接打開

    • 對于多線程應用,考慮使用連接池?

  2. 參數化查詢

    • 始終使用參數化查詢防止SQL注入

    • 不要通過字符串拼接構建SQL語句

  3. 事務使用

    • 批量操作使用事務提高性能

    • 保持事務盡可能短小

    • 正確處理事務的異常情況

  4. 性能考慮

    • 為頻繁查詢的列創建索引

    • 使用EXPLAIN QUERY PLAN分析查詢性能

    • 大量數據操作時考慮批處理

  5. 版本兼容性

    • 確認目標SQLite版本是否支持需要的功能

    • 窗口函數需要SQLite 3.25+

    • FTS5需要特殊編譯支持

以上就是關于如何在C#中使用SQLite數據庫的基本流程,下一節我們將通過其他的C#示例代碼來講解SQLite高級功能的實現!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81048.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81048.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81048.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視頻圖像壓縮領域中 DCT 的 DC 系數和 AC 系數詳解

引言 在數字圖像與視頻壓縮領域&#xff0c;離散余弦變換&#xff08;Discrete Cosine Transform, DCT&#xff09;憑借其卓越的能量集中特性&#xff0c;成為JPEG、MPEG等國際標準的核心技術。DCT通過將空域信號映射到頻域&#xff0c;分離出DC系數&#xff08;直流分量&…

對抗系統熵增:從被動救火到主動防御的穩定性實戰

&#x1f4d5;我是廖志偉&#xff0c;一名Java開發工程師、《Java項目實戰——深入理解大型互聯網企業通用技術》&#xff08;基礎篇&#xff09;、&#xff08;進階篇&#xff09;、&#xff08;架構篇&#xff09;清華大學出版社簽約作家、Java領域優質創作者、CSDN博客專家、…

java 中 DTO 和 VO 的核心區別

DTO 和 VO 的核心區別 特性DTO&#xff08;數據傳輸對象&#xff09;VO&#xff08;視圖對象&#xff09;設計目的服務層與外部系統&#xff08;如前端、其他服務&#xff09;之間的數據傳輸為前端展示層定制數據&#xff0c;通常與 UI 強綁定數據內容可能包含業務邏輯需要的字…

數據結構【二叉樹的遍歷實現】

&#x1f4d8;考研數據結構基礎&#xff1a;二叉樹的存儲、遍歷與隊列輔助實現詳 在數據結構的學習中&#xff0c;二叉樹作為一種結構清晰、應用廣泛的樹形結構&#xff0c;是考研計算機專業課中重點內容之一。本文將以實際代碼為基礎&#xff0c;介紹二叉樹的存儲結構、遍歷方…

無人機俯視風光攝影Lr調色預設,手機濾鏡PS+Lightroom預設下載!

調色詳情 無人機俯視風光攝影 Lr 調色是利用 Adobe Lightroom 軟件&#xff0c;對無人機從俯視角度拍攝的風光照片進行后期處理的調色方式。通過調整色彩、對比度、光影等多種參數&#xff0c;能夠充分挖掘并強化畫面獨特視角下的壯美與細節之美&#xff0c;讓原本平凡的航拍風…

【springcloud學習(dalston.sr1)】Eureka服務端集群的搭建(含源代碼)(二)

該系列項目整體介紹及源代碼請參照前面寫的一篇文章【springcloud學習(dalston.sr1)】項目整體介紹&#xff08;含源代碼&#xff09;&#xff08;一&#xff09; 這篇文章主要介紹多個eureka服務端的集群環境是如何搭建的。 &#xff08;一&#xff09;eureka的簡要說明 Eu…

互聯網大廠Java求職面試實戰:Spring Boot微服務與數據庫優化詳解

&#x1f4aa;&#x1f3fb; 1. Python基礎專欄&#xff0c;基礎知識一網打盡&#xff0c;9.9元買不了吃虧&#xff0c;買不了上當。 Python從入門到精通 &#x1f601; 2. 畢業設計專欄&#xff0c;畢業季咱們不慌忙&#xff0c;幾百款畢業設計等你選。 ?? 3. Python爬蟲專欄…

事件驅動reactor的原理與實現

fdset 集合&#xff1a;&#xff08;就是說&#xff09; fd_set是一個位圖&#xff08;bitmap&#xff09;結構 每個位代表一個文件描述符 0表示不在集合中&#xff0c;1表示在集合中 fd_set結構&#xff08;簡化&#xff09;&#xff1a; [0][1][2][3][4][5]...[1023] …

一分鐘在Cherry Studio和VSCode集成火山引擎veimagex-mcp

MCP的出現打通了AI模型和外部數據庫、網頁API等資源&#xff0c;成倍提升工作效率。近期火山引擎團隊推出了 MCP Server SDK&#xff1a; veimagex-mcp。本文介紹如何在Cherry Studio 和VSCode平臺集成 veimagex-mcp。 什么是MCP MCP&#xff08;Model Context Protocol&…

掌控隨心 - 服務網格的流量管理藝術 (Istio 實例)

掌控隨心 - 服務網格的流量管理藝術 (Istio 實例) 想象一下,沒有服務網格的時候,我們要實現像“將 1% 的用戶流量導入到新版本應用”、“根據用戶設備類型訪問不同后端”、“模擬下游服務故障”這類高級流量策略,通常需要在代碼、負載均衡器、API 網關等多個地方進行復雜且分…

[ARM][匯編] 01.基礎概念

目錄 1.全局標號 1.1.使用方法 1.1.1.聲明全局標號 1.1.2.定義全局標號 1.1.3.引用全局標號 1.2.全局標號與局部標號的區別 1.3.注意事項 2.局部標號 2.1.使用方法 2.1.1.定義局部標號 2.1.2.跳轉引用 2.2.局部標號與全局標號的對比 2.3.注意事項 3.符號定義偽指…

如何使用遠程桌面控制電腦

目的&#xff1a; 通過路由器使用pc控制臺式機&#xff0c;實現了有線/無線pc與臺式機的雙向遠程桌面控制 最核心就兩條&#xff1a;get ip地址與被控制機器的賬戶與密碼。 現象挺神奇&#xff1a;被控制電腦的電腦桌面處于休眠模式&#xff0c;此時強行喚醒被控電腦會導致中斷…

Hive表JOIN性能問

在處理100TB的Hive表JOIN性能問題時&#xff0c;需采用分層優化策略&#xff0c;結合數據分布特征、存儲格式和計算引擎特性。以下是系統性優化方案&#xff1a; 1. 數據傾斜優化&#xff08;Skew Join&#xff09; 1.1 識別傾斜鍵 方法&#xff1a;統計JOIN鍵的分布頻率&…

MongoDB 的核心概念(文檔、集合、數據庫、BSON)是什么?

MongoDB 是一個面向文檔的數據庫&#xff0c;它的核心概念與傳統的關系型數據庫&#xff08;RDBMS&#xff09;有所不同。以下是它的四個主要核心概念&#xff1a; 文檔 (Document) 定義&#xff1a; 文檔是 MongoDB 中的基本數據單元。它類似于關系型數據庫中的一行記錄&#…

AI智慧公園管理方案:用科技重塑市民的“夜游體驗”

AI智慧公園管理方案&#xff1a;多場景智能巡檢與安全防控 一、背景與痛點分析 夏季夜間&#xff0c;公園成為市民休閑娛樂的核心場所&#xff0c;但管理難度隨之激增&#xff1a; 寵物管理失控&#xff1a;未牽繩寵物進入園區&#xff0c;隨地排泄、驚擾游客&#xff0c;甚…

Spring Cloud Gateway 聚合 Swagger 文檔:一站式API管理解決方案

前言 在微服務架構中&#xff0c;隨著服務數量的增加&#xff0c;API文檔管理變得越來越復雜。每個微服務都有自己的Swagger文檔&#xff0c;開發人員需要記住每個服務的文檔地址&#xff0c;這無疑增加了開發難度。本文將介紹如何使用Spring Cloud Gateway聚合所有微服務的Sw…

尼康VR鏡頭防抖模式NORMAL和ACTIVE的區別(私人筆記)

1. NORMAL 模式&#xff08;常規模式&#xff09; 適用場景&#xff1a;一般手持拍攝&#xff0c;比如人像、靜物、風景或緩慢平移鏡頭&#xff08;如水平追拍&#xff09;等。工作特性&#xff1a; 補償手抖引起的小幅度震動&#xff08;比如手持時自然的不穩&#xff09;&am…

Babylon.js學習之路《四、Babylon.js 中的相機(Camera)與視角控制》

文章目錄 1. 引言&#xff1a;為什么相機是 3D 場景的“眼睛”&#xff1f;1.1 相機的核心作用1.2 常見相機類型概覽 2. 相機基礎參數解析2.1 通用屬性2.2 相機坐標系 3. 詳解常用相機類型3.1 自由相機&#xff08;FreeCamera&#xff09;3.2 弧形旋轉相機&#xff08;ArcRotat…

【Python】普通方法、類方法和靜態方法的區分

Python 中普通方法、類方法和靜態方法的區分 下面我將從多個維度對這三種方法進行詳細對比&#xff0c;并通過示例說明它們的使用場景和區別。 1. 核心區別總結 特性普通方法(實例方法)類方法(classmethod)靜態方法(staticmethod)定義裝飾器無classmethodstaticmethod第一個…

geoserver發布arcgis瓦片地圖服務(最新版本)

第一步&#xff1a;下載geoserver服務&#xff0c;進入bin目錄啟動 需要提前安裝好JDK環境&#xff0c;1.8及以上版本 安裝完成&#xff0c;頁面訪問端口&#xff0c;進入控制臺界面,默認用戶名密碼admin/geoserver 第二步&#xff1a;下載地圖 破解版全能電子地圖下載器&…