一,SQLite数据库简介
SQLite是可以实现类似于关系型数据库中各种操作的事务性SQL数据库引擎,可以为应用程序提供存储于本地的嵌入式数据库,帮助应用程序实现轻量级的数据存储。
SQLite是一个库文件,并不是单独的进程,它可以静态或动态链接到C++应用程序中,然后应用程序可以利用SQLite提供的编程接口进行访问和处理SQLite存储文件,存储文件一般带有".db"后缀。
在C/C++开发场景使用SQLite,上手特别容易,前期只需要在文件系统中创建一个新文件并调用SQLite提供的C/C++函数去连接即可。
SQLite的设计初衷是为了替代更复杂和重量级的数据库引擎,例如MySQL、PostgreSQL等。如今,SQLite已被广泛使用在应用程序开发场景,包括Web浏览器、移动端APP、嵌入式软件等。
SQLite具有以下优点:
1.轻量级且没有外部依赖
2.使用简单,不需要配置。
3.支持多进程或多线程安全访问。
4.支持跨平台,支持Linux、Mac、Windows等多平台部署。
5.无服务数据库引擎,不需要单独维护和部署。
6.访问速度快,可以替代XML、JSON、CSV等本地文件格式。
二,SQLite的安装与集成
1.SQLite在Linux环境下的安装
sudo apt install sqlite3
安装成功以后,在shell界面输入"sqlite3"命令即可进入sqlite3命令行界面。
root@ubuntu:/home/sqlite_demo# sqlite3
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
2.SQLite在Linux环境下的集成
step.01.在官网下载压缩包
https://www.sqlite.org/2024/sqlite-autoconf-3460000.tar.gz
step.02.运行以下命令进行解压&编译
tar -zxvf sqlite-autoconf-3460000.tar.gz
cd sqlite-autoconf-3460000
./configure
make
make install
编译完成以后,默认情况下会在"/usr/local/"路径生成对应的头文件和so动态库文件。
三,SQLite命令行简介
SQLite支持使用命令行与关系型数据库进行交互,SQLite命令行类似于SQL语句,可以完成创建(Create),查询(Select),插入(Insert)等操作。
在命令行界面输入".help"可以查看所有的命令:
1.常用的基础命令
命令 | 含义 |
---|---|
.backup ?DB? FILE | 备份数据库到文件 |
.bail on|off | 遇到错误后停止 |
.databases | 列出数据库的名称和文件名 |
.tables | 列出数据库中的所有表 |
.import FILE TABLE | 将文件的数据导入到Table表 |
.log FILE|off | 打开或关闭日志记录 |
.schema | 获取表的完整信息 |
.exit | 退出命令行界面 |
2.命令行实战
step.01.创建数据库
> sqlite3 testDB.db
step.02.创建table表
sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
sqlite> .tables
step.03.查看表的结构
sqlite>.schema COMPANY
四,SQLite常用的SQL语句
SQLite的内部实现符合ACID标准,并且支持大多数SQL语法标准。
CREATE TABLE:在数据库中创建一个新表
ALTER TABLE:修改数据库中现有的表
DROP TABLE:从数据库中删除表
CREATE INDEX:在表上创建新的索引
DROP INDEX:从表中删除索引
INSERT INTO:往表中插入新的行
UPDATE:更新表中的数据
DELETE FROM:从表中删除数据
SELECT:从表中检索数据
JOIN:基于公共字段从多个表中检索数据
GROUP BY:按一个或多个字段对查询结果进行分组
HAVING:根据条件筛选查询结果
1.CREATE TABLE语句示例
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
.....
columnN datatype,
PRIMARY KEY( one or more columns ));
2.DELETE语句示例
DELETE FROM table_name
WHERE {CONDITION};
3.INSERT INTO语句示例
INSERT INTO table_name(
column1,
column2,
....columnN)
VALUES ( value1, value2, ....valueN);
4.SELECT WHERE语句示例
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION;
五,SQLite支持的数据类型
1.SQLite数据库支持以下数据类型:
NULL:表示值为NULL。
INTEGER:表示整数。
REAL:表示浮点数。
TEXT:表示文本字符串。
BLOB:表示二进制数据。
2.SQLite数据库支持以下约束:
PRIMARY KEY:用于指定主键列。
AUTOINCREMENT:用于指定自动递增列。
NOT NULL:用于指定不为NULL值的列。
UNIQUE:用于指定值唯一的列。
六,SQLite常用的函数接口
sqlite3_open:打开与SQLite数据库文件的连接
sqlite3_close:关闭与SQLite数据库文件的连接
sqlite3_exec:执行SQL语句
sqlite3_stmt:初始化SQL语句对象
sqlite3_prepare:编译好语句对象中的SQL代码
sqlite3_step:执行下一条编译好的SQL语句
sqlite3_column:获取执行结果的列值
sqlite3_finalize:释放SQL语句对象
七,C++代码实战
场景:Person表的结构如下
Person | |
---|---|
ID | INT |
NAME | TEXT |
AGE | INT |
ADDRESS | CHAR(50) |
SALARY | REAL |
Demo1.新建数据库
主要调用接口:sqlite3_open/sqlite3_close
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
int main() {
sqlite3 *db;
int rc;
//如果数据库文件不存在,则新建该文件
rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
}
else
{
fprintf(stderr, "Opened database successfully\n");
}
sqlite3_close(db);
return 0;
}
编译运行结果:
g++ create_db.cpp -l sqlite3 -o create_db
Opened database successfully
运行结束可以在本地看到test.db文件。
Demo2.新建Table表
主要调用接口:sqlite3_exec
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
int main(int argc, char** argv){
sqlite3* DB;
std::string sql = "CREATE TABLE PERSON("
"ID INT PRIMARY KEY NOT NULL,"
"NAME TEXT NOT NULL,"
"AGE INT NOT NULL,"
"ADDRESS CHAR(50),"
"SALARY REAL );";
int exit = 0;
exit = sqlite3_open("test.db", &DB);
char* messaggeError;
exit = sqlite3_exec(DB, sql.c_str(), NULL, 0, &messaggeError);
if (exit != SQLITE_OK) {
std::cerr << "Error Create Table" << std::endl;
sqlite3_free(messaggeError);
}
else
std::cout << "Table created Successfully" << std::endl;
sqlite3_close(DB);
return (0);
}
编译运行结果:
g++ create_table.cpp -l sqlite3 -o create_table
Table created Successfully
Demo3. 插入和删除数据
callback函数用于打印select结果
typedef int (*sqlite3_callback)(
void*, /* Data provided in the 4th argument of sqlite3_exec() */
int, /* The number of columns in row */
char**, /* An array of strings representing fields in the row */
char** /* An array of strings representing column names */
);
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
using namespace std;
static int callback(void* data, int argc, char** argv, char** azColName)
{
int i;
fprintf(stderr, "%s: ", (const char*)data);
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main()
{
sqlite3* DB;
char* messaggeError;
int exit = sqlite3_open("test.db", &DB);
string query = "SELECT * FROM PERSON;";
cout << "STATE OF TABLE BEFORE INSERT" << endl;
sqlite3_exec(DB, query.c_str(), callback, NULL, NULL);
string sql("INSERT INTO PERSON VALUES(1, 'GATES', 30, 'PALO ALTO', 100.0);"
"INSERT INTO PERSON VALUES(2, 'ALLEN', 20, 'SEATTLE', 30.22);"
"INSERT INTO PERSON VALUES(3, 'JOBS', 24, 'SEATTLE', 99.0);");
exit = sqlite3_exec(DB, sql.c_str(), NULL, 0, &messaggeError);
if (exit != SQLITE_OK) {
std::cerr << "Error Insert" << std::endl;
sqlite3_free(messaggeError);
}
else
{
std::cout << "Records created Successfully!" << std::endl;
}
cout << "STATE OF TABLE AFTER INSERT" << endl;
sqlite3_exec(DB, query.c_str(), callback, NULL, NULL);
sql = "DELETE FROM PERSON WHERE ID = 2;";
exit = sqlite3_exec(DB, sql.c_str(), NULL, 0, &messaggeError);
if (exit != SQLITE_OK) {
std::cerr << "Error DELETE" << std::endl;
sqlite3_free(messaggeError);
}
else
{
std::cout << "Record deleted Successfully!" << std::endl;
}
cout << "STATE OF TABLE AFTER DELETE OF ELEMENT" << endl;
sqlite3_exec(DB, query.c_str(), callback, NULL, NULL);
sqlite3_close(DB);
return (0);
}
编译运行结果:
g++ insert_delete.cpp -l sqlite3 -o insert_delete
STATE OF TABLE BEFORE INSERT
Records created Successfully!
STATE OF TABLE AFTER INSERT
(null): ID = 1
NAME = GATES
AGE = 30
ADDRESS = PALO ALTO
SALARY = 100.0
(null): ID = 2
NAME = ALLEN
AGE = 20
ADDRESS = SEATTLE
SALARY = 30.22
(null): ID = 3
NAME = JOBS
AGE = 24
ADDRESS = SEATTLE
SALARY = 99.0
Record deleted Successfully!
STATE OF TABLE AFTER DELETE OF ELEMENT
(null): ID = 1
NAME = GATES
AGE = 30
ADDRESS = PALO ALTO
SALARY = 100.0
(null): ID = 3
NAME = JOBS
AGE = 24
ADDRESS = SEATTLE
SALARY = 99.0
Demo4. 查询数据
#include <iostream>
#include <sqlite3.h>
#include <stdio.h>
using namespace std;
static int callback(void* data, int argc, char** argv, char** azColName)
{
int i;
fprintf(stderr, "%s: ", (const char*)data);
for (i = 0; i < argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main()
{
sqlite3* DB;
int exit = 0;
exit = sqlite3_open("test.db", &DB);
string data("CALLBACK FUNCTION");
string sql("SELECT * FROM PERSON;");
if (exit) {
std::cerr << "Error open DB " << sqlite3_errmsg(DB) << std::endl;
return (-1);
}
else
std::cout << "Opened Database Successfully!" << std::endl;
int rc = sqlite3_exec(DB, sql.c_str(), callback, (void*)data.c_str(), NULL);
if (rc != SQLITE_OK)
cerr << "Error SELECT" << endl;
else {
cout << "Operation OK!" << endl;
}
sqlite3_close(DB);
return (0);
}
编译运行结果:
g++ select.cpp -l sqlite3 -o select
Opened Database Successfully!
CALLBACK FUNCTION: ID = 1
NAME = GATES
AGE = 30
ADDRESS = PALO ALTO
SALARY = 100.0
CALLBACK FUNCTION: ID = 3
NAME = JOBS
AGE = 24
ADDRESS = SEATTLE
SALARY = 99.0
Operation OK!
如果删除了本地的test.db文件,运行结果如下:
Opened Database Successfully!
Error SELECT
八,参考阅读
https://zetcode.com/db/sqlitec/
https://sqlite.readdevdocs.com/cintro.html
https://www.tutorialspoint.com/sqlite/sqlite_installation.htm
https://www.sqlite.org/cintro.html
https://www.geeksforgeeks.org/sql-using-c-c-and-sqlite/