day39 SQLite数据库操作与HTML核心API及页面构建
一、SQLite数据库核心操作
1. 基础概念与特性
SQLite是一个轻量级的嵌入式数据库,具有以下特点:
- 无需独立服务器进程
- 数据库存储在一个普通文件中
- 支持标准SQL语法的大部分功能
- 适合嵌入式系统和小型应用
2. 数据类型与亲和性规则
SQLite使用动态类型系统,根据"类型亲和性"(Type Affinity)规则自动转换数据类型:
声明类型示例 | 转换结果 | 规则 |
---|---|---|
INT, INTEGER, TINYINT, … INT8 | INTEGER | 1 |
CHARACTER(20), VARCHAR(255), TEXT | TEXT | 2 |
BLOB, 无类型声明 | BLOB | 3 |
REAL, DOUBLE, FLOAT | REAL | 4 |
NUMERIC, DECIMAL, BOOLEAN, DATE | NUMERIC | 5 |
重要特性:
- 括号内参数(如
VARCHAR(255)
)被忽略(SQLite无长度限制) - 类型名称按后缀匹配:
FLOATING POINT
→ 含INT
→INTEGER
亲和性(非REAL)STRING
→ 无匹配规则 →NUMERIC
亲和性(规则5)
- 实际存储时
char
类型被转换为TEXT
3. 时间操作与表结构创建
SQLite使用datetime类型处理时间数据,支持内置函数操作时间值:
-- 创建包含时间列的表(id整数, name字符, age整数, dt时间)
CREATE TABLE user1(id int, name char, age int, dt datetime);
-- 插入数据:使用datetime函数生成带时区的当前时间
-- 注意:SQLite中char实际存储为TEXT类型
insert into user1 values (2, '张三', 23, datetime('now', '+8 hours'));
-- 查询当前系统时间(+8小时时区转换)
select datetime('now', '+8 hours');
理想运行结果:
2023-10-05 14:30:45
(实际输出为当前时间+8小时,如东八区时间)
4. 自动增长列实现
SQLite通过INTEGER PRIMARY KEY
实现自动增长(无需AUTOINCREMENT):
-- 创建自动增长主键表(id自增, name字符, age整数, dt时间)
CREATE TABLE user3(id INTEGER PRIMARY KEY ASC, name char, age int, dt datetime);
-- 插入数据:id列传入NULL触发自增
-- 注意:SQLite中char实际存储为TEXT类型
insert into user3 values (NULL, '李四', 23, datetime('now'));
关键说明:
(void*)0
表示SQLite内部将NULL
转换为自增值(首条记录id=1)- 插入时指定
NULL
触发自增 ASC
表示升序增长(默认行为)
5. 高级查询语法
-- 组合查询:WHERE过滤 + ORDER BY排序 + LIMIT限制
select * from user where id<10 order by id limit 2;
执行逻辑:
WHERE id<10
:筛选ID小于10的记录ORDER BY id
:按ID升序排序(默认ASC)LIMIT 2
:仅返回前2条结果
理想结果:
id | name | age | dt |
---|---|---|---|
1 | 张三 | 23 | 2023-10-05 14:00:00 |
2 | 李四 | 23 | 2023-10-05 14:05:00 |
6. 数据库维护命令
数据导出与导入:
# 导出整个数据库为SQL脚本(> 重定向输出)
sqlite3 xxx.db .dump > xxx.sql
# 导入SQL脚本重建数据库(< 重定向输入)
sqlite3 new.db < xxx.sql
执行效果:
.dump
生成包含CREATE TABLE
和INSERT
语句的完整脚本- 导入后
new.db
与原数据库结构数据完全一致 - 脚本包含事务控制:
BEGIN TRANSACTION;
和COMMIT;
可视化工具安装:
sudo apt-get install sqlitebrowser # Ubuntu/Debian安装命令
作用: 提供图形界面操作数据库(建表、查询、导入导出等)
7. 查询操作 API
1) sqlite3_get_table()(仅用于SELECT)
int sqlite3_get_table(
sqlite3 *db, // 数据库连接句柄
char *sql, // SELECT查询语句
char ***resultp, // 三级指针接收结果集([0]=列名, [1]=行1数据...)
int *nrow, // 输出:结果行数
int *ncol, // 输出:结果列数
char **errmsg // 错误信息存储地址
);
特点:
- 专为
SELECT
设计,返回完整结果集 - 需手动释放内存:
sqlite3_free_table(resultp)
2) sqlite3_exec()(通用操作)
int sqlite3_exec(
sqlite3 *db, // 数据库连接句柄
const char *sql, // SQL语句(支持多条)
sqlite3_callback, // 回调函数(处理SELECT结果)
void *arg, // 传递给回调的参数
char **errmsg // 错误信息
);
关键行为:
- 执行
INSERT/DELETE/UPDATE
时无需回调 SELECT
时通过回调函数逐行处理结果- 回调返回非0 → 中断执行并返回
SQLITE_ABORT
8. 完整查询示例(C语言实现)
示例1:控制台输出查询结果
#include <sqlite3.h> // 引入SQLite数据库操作库
#include <stdio.h> // 引入标准输入输出库
// SQLite查询结果回调函数:用于处理并显示查询结果
// 参数说明:
// arg: 由sqlite3_exec传入的用户数据(此处未使用)
// col: 查询结果的列数
// result: 存储查询结果数据的指针数组(当前行数据)
// title: 存储列名的指针数组
int show(void* arg, int col, char** result, char** title)
{
static int flag = 0; // 静态变量,用于标记是否是第一次调用(控制只打印一次列名)
int i = 0;
// 第一次调用时打印列名
if (0 == flag)
{
flag = 1; // 修改标记,确保列名只打印一次
for (i = 0; i < col; i++)
{
printf("%s\t", title[i]); // 打印列名,用制表符分隔
}
}
printf("\n"); // 换行,准备打印一行数据
// 循环打印当前行的每一列数据
for (i = 0; i < col; i++)
{
printf("%s\t", result[i]); // 打印数据,用制表符分隔
}
printf("\n"); // 一行数据打印完成后换行
return 0; // 回调函数返回0表示继续处理后续结果
}
int main(int argc, char** argv)
{
sqlite3* db = NULL; // 声明SQLite数据库连接句柄
char* errmsg = NULL; // 声明用于存储SQL操作错误信息的指针
// 打开名为aaa.db的数据库文件
int ret = sqlite3_open("./aaa.db", &db);
// 检查数据库打开是否成功
if (SQLITE_OK != ret)
{
fprintf(stderr, " sqlite3_open %s\n", sqlite3_errstr(ret)); // 输出打开失败的错误信息
sqlite3_close(db); // 关闭数据库连接
return 1; // 程序异常退出
}
// 定义查询SQL命令:查询user表中的所有记录
char sql_cmd[] = "select * from user;";
// 执行SQL查询,指定show函数作为结果处理的回调函数
ret = sqlite3_exec(db, sql_cmd, show, NULL, &errmsg);
// 检查查询执行是否成功
if (SQLITE_OK != ret)
{
// 输出查询失败的错误信息,包含执行的SQL命令和具体错误
fprintf(stderr, " sqlite3_exec sql_cmd:[%s] %s\n", sql_cmd, errmsg);
sqlite3_free(errmsg); // 释放错误信息占用的内存
sqlite3_close(db); // 关闭数据库连接
return 1; // 程序异常退出
}
sqlite3_close(db); // 关闭数据库连接
return 0; // 程序正常退出
}
理想运行结果(假设 user 表包含以下数据):
id | name | age |
---|---|---|
1 | 张三 | 23 |
2 | 李四 | 25 |
程序输出:
id name age
1 张三 23
2 李四 25
执行流程:
- 首次回调:打印列名
id name age
- 后续回调:逐行打印数据(每行换行分隔)
- 无错误时正常退出(返回0)
示例2:将查询结果写入文件
#include <sqlite3.h> // 引入SQLite数据库操作库
#include <stdio.h> // 引入标准输入输出库
// SQLite查询结果回调函数:将查询结果写入文件
// 参数说明:
// arg: 由sqlite3_exec传入的用户数据(此处为文件指针)
// col: 查询结果的列数
// result: 存储查询结果数据的指针数组
// title: 存储列名的指针数组
int show(void* arg, int col, char** result, char** title)
{
FILE* fp = (FILE*)arg; // 将传入的用户数据转换为文件指针
static int flag = 0; // 静态变量,标记是否首次调用(控制列名只输出一次)
int i = 0;
// 首次调用时,写入列名到文件
if (0 == flag)
{
flag = 1; // 修改标记,确保列名只写入一次
for (i = 0; i < col; i++)
{
fprintf(fp, "%s\t", title[i]); // 写入列名,用制表符分隔
}
}
fprintf(fp, "\n"); // 换行,准备写入一行数据
// 循环写入当前行的每一列数据
for (i = 0; i < col; i++)
{
fprintf(fp, "%s\t", result[i]); // 写入数据,用制表符分隔
}
return 0; // 回调函数返回0表示继续处理后续结果
}
int main(int argc, char** argv)
{
sqlite3* db = NULL; // 声明SQLite数据库连接句柄
char* errmsg = NULL; // 声明用于存储SQL操作错误信息的指针
// 打开名为aaa.db的数据库文件
int ret = sqlite3_open("./aaa.db", &db);
// 检查数据库打开是否成功
if (SQLITE_OK != ret)
{
fprintf(stderr, " sqlite3_open %s\n", sqlite3_errstr(ret)); // 输出打开失败的错误信息
sqlite3_close(db); // 关闭数据库连接
return 1; // 程序异常退出
}
// 打开(或创建)a.txt文件,用于写入查询结果
FILE* fp = fopen("a.txt", "w");
if (NULL == fp) // 检查文件打开是否成功
{
perror("fopen"); // 输出文件打开失败的错误信息
return 1; // 程序异常退出
}
// 定义查询SQL命令:查询user表中的所有记录
char sql_cmd[] = "select * from user;";
// 执行SQL查询,指定show为回调函数,并将文件指针fp作为参数传入
ret = sqlite3_exec(db, sql_cmd, show, fp, &errmsg);
// 检查查询执行是否成功
if (SQLITE_OK != ret)
{
// 输出查询失败的错误信息,包含执行的SQL命令和具体错误
fprintf(stderr, " sqlite3_exec sql_cmd:[%s] %s\n", sql_cmd, errmsg);
sqlite3_free(errmsg); // 释放错误信息占用的内存
sqlite3_close(db); // 关闭数据库连接
fclose(fp); // 关闭文件
return 1; // 程序异常退出
}
fclose(fp); // 关闭文件
sqlite3_close(db); // 关闭数据库连接
return 0; // 程序正常退出
}
理想运行结果:
执行后生成 a.txt
文件,内容如下:
id name age
1 张三 23
2 李四 25
关键提示:
- 实际开发中需处理
errmsg
释放(示例已包含sqlite3_free(errmsg)
) - 回调函数返回值控制执行流程(非0中断)
char** result
中空值以NULL
表示(需在回调中判空)- 如果查询结果为空,回调函数不会被调用
二、HTML核心API与页面构建
1. HTML文档基本结构
基础HTML文档示例:
<!DOCTYPE html> <!-- 文档类型声明,指定使用HTML5标准 -->
<html> <!-- HTML文档的根元素 -->
<head> <!-- 文档头部,包含元数据 -->
<meta charset="utf-8"> <!-- 指定字符编码为UTF-8 -->
<title>中文测试。。。。</title> <!-- 浏览器标签页显示的标题 -->
</head>
<body> <!-- 文档主体,包含可见内容 -->
这里是测试body测试内容。。。
</body>
</html>
理想显示效果:
- 浏览器标签页标题显示"中文测试。。。。"
- 页面正文显示"这里是测试body测试内容。。。"
- 支持中文显示(因设置了UTF-8编码)
2. 常用HTML标签与元素属性
2.1 标题与段落标签
标题标签:
<h1>一级标题</h1> <!-- 最大标题,加粗并自动换行 -->
<h2>二级标题</h2>
<h3>三级标题</h3>
<h4>四级标题</h4>
<h5>五级标题</h5>
<h6>六级标题</h6> <!-- 最小标题,加粗并自动换行 -->
特点:
- h1 到 h6 为双标签
- 自动加粗并换行
- 数字越小,标题越大
段落与分割标签:
<p>这是一个段落文本。</p> <!-- 段落标签,自动添加上下空白并换行 -->
<p>这是另一个段落。</p>
<hr> <!-- 水平线标签,单标签,创建从左到右的分割线 -->
特点:
<p>
为双标签,定义段落,自动添加上下空白并换行<hr>
为单标签,创建水平分割线
2.2 文本格式化标签
<b>内容</b> <!-- 加粗 -->
<br> <!-- 换行,如果是p标签中间有间隔 -->
<i>内容</i> <!-- 字体倾斜 -->
<del>内容</del> <!-- 删除文字 -->
<strong>内容</strong> <!-- 强调一段文字,效果类似b标签 -->
<u>内容</u> <!-- 下划线 -->
<small>内容</small> <!-- 超小字体 -->
<sub>内容</sub> <!-- 下标 -->
<sup>内容</sup> <!-- 上标 -->
h<sub>2</sub>0 <!-- 显示为:h₂0 -->
100m<sup>2</sup> <!-- 显示为:100m² -->
<ruby>二姐 <rt>(er) (jie)</rt></ruby> <!-- 拼音,可能部分浏览器不支持 -->
<mark>内容</mark> <!-- 加黄色背景 -->
2.3 列表标签
无序列表:
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
- 有个
type
属性 文字最前面的符号disc
黑色实心圆circle
白色空心圆square
黑色方块
有序列表:
<ol>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ol>
- 其中可以放文字,图片,或链接
- 有
type
属性,设置排序使用什么数字 start
开始值,后面的++;
2.4 表格标签
表格的构成:
table
,外框tr
行td
列
<table>
<tr><td>1-1</td><td>1-2</td><td>1-3</td></tr>
<tr><td>2-1</td><td>2-2</td><td>2-3</td></tr>
<tr><td>3-1</td><td>3-2</td><td>3-3</td></tr>
</table>
3行 3列
表格的属性
border
边框粗细th
,是tr的属性,列标题,自动居中,加粗colspan
,横向合并单元格,需要整形参数
<tr><th colspan="3">name</th></tr>
表格的合并
rowspan
,列项合并,整数参数
3. 超链接与图像
3.1 超链接
5种形式:
- 链接外部网站
- 链接本地文件
- 图片链接
- 电子邮件链接打开电子邮件
- 下载文件链接
<a href="http://www.baidu.com">baidu</a> <!-- 外部网站链接 -->
<br><a href="1.html">1111</a> <!-- 本地文件链接 -->
<br><a href="1.html"><img src="abc.jpg"></a> <!-- 图片链接 -->
<br><a href="mailto:123@13.com">contract me</a> <!-- 电子邮件链接 -->
<br><a href="abc.jpg">下载</a> <!-- 下载文件链接 -->
target 属性:
_self
: 当前位置打开(默认值)_blank
: 新窗口中打开
<a href="http://www.baidu.com" target="_blank">baidu</a>
3.2 图像标签 (img)
<img src="abc.jpg" alt="美女" width="100" height="200">
<img src="abc.jpg" alt="美女" width="50%" height="200%">
属性说明:
src
:图像来源alt
:如果不能正确打开,显示的文字width
,height
:设置图像宽高
注意: 百分比是相对于网页而言的,高度百分比在某些浏览器中可能无效
4. 表单元素
<form></form>
<!-- 表单中重要的字元素 input button -->
<!-- 属性 action,指定表单发送的地址 -->
<!-- 属性 method 发送的方式 get,post -->
<!-- get方法 数据会附加到url的后面传递给服务器 默认 -->
<!-- post,将数据包大包发给服务器,等候服务器来读取 -->
input元素(输入框):是表单的一个字属性
- 指定表单中的内容项,比如输入内容的文本框
- 可以指定表单属性,也可以放在表单的外面
- input元素的属性:
type
,指定输入框的类型,text
单行文本,password
密码,submit
提交按钮,
reset
,重置按键,button
按键,普通的按键需要和特定的时间关联。
image
:图片式按键
hidden
:隐藏字段,该内容不显示在页面上,提交其他的一些变量。
email
: 是一个邮箱类型,新特性,可能支持有差异
required
:表示内容必须填写,不然不能提交。name
:名称,输入内容识别名称,传递参数时候的参数名称value
: 默认值,输入框默认填入的内容maxlength
,指定最大长度placeholder
,设置提示信息的
5. 完整HTML示例
示例1:基础页面
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8"> <!-- 这个是设置字符集的 -->
<title>中文测试。。。。</title>
<style>
body {
background-color: #00FFFF;
}
</style>
</head>
<body>
这里是测试body测试内容。。。
<h1> h1字体 </h1>
<h3 align='center'> h3字体 </h3>
<h6 align='right'> h6字体 </h6>
<h3><p>其次,<br><br>制裁表明中国政治立场与主权底线的红线不可逾越。</p></h3><hr><h1><p>陈洋说,石平是日本国内非常"资深"的反华派,不仅长期在右翼反华媒体就涉台、钓鱼岛、历史等议题公开发表荒谬错误言论,迎合右翼反华势力</p></h1>
<b>加粗内容</b> <i>字体倾斜</i> <del>删除文字</del> <u>下划线</u> <small>超小字体</small>h<sub>2</sub>0 100m<sup>2</sup>
<ruby>二姐 <rt>(er) (jie)<rt></ruby> <mark> 加黄色背景</mark>
<a href="http://www.baidu.com">baidu</a> <a href="02.html">go to 2</a> <a href="http://www.taobao.com"><img src="1.png"></a> <a href="mailto:123@13.com">联系本站管理员</a> <a href="1.7z">下载</a>
<img src="1.gif" alt="帅哥" width="200" height="200">
<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
<ol>
<li>列 表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ol>
<table border=1 >
<tr><td>1-1</td><td>1-2</td><td>1-3</td></tr>
<tr><td>2-1</td><td>2-2</td><td>2-3</td></tr>
<tr><td>3-1</td><td>3-2</td><td>3-3</td></tr>
</table>
<table border=1 >
<tr><th colspan="3">1-1</th></tr>
<tr><td>2-1</td><td>2-2</td><td>2-3</td></tr>
<tr><td>3-1</td><td>3-2</td><td>3-3</td></tr>
</table>
<table border=1 >
<tr><th rowspan="3">1-1</th><td>1-2</td><td>1-3</td></tr>
<tr><td>2-2</td><td>2-3</td></tr>
<tr><td>3-2</td><td>3-3</td></tr>
</table>
</body>
</html>
示例2:登录表单
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8"> <!-- 这个是设置字符集的 -->
<title>登录</title>
<style>
body {
background-color: #F0F8FF;
}
</style>
</head>
<body>
<form action='http://www.baidu.com'>
用户名: <input type ='text' name='username' required='required' placeholder='请输入qq的账号'>
密码: <input type ='password' name='userpw' required='required' placeholder='请输入qq的密码' > <input type='submit' >
</form>
</body>
</html>
6. 注释与HTML实体
注释:
<!-- 这是一个HTML注释,不会在页面中显示 -->
<p>可见内容</p>
<!--
多行注释示例
这些内容都不会显示在页面上
-->
特点:
- 以
<!--
开始,-->
结束 - 注释内容不会在浏览器中显示
- 可用于多行注释
HTML 实体:
- 用于输出一些特殊的字符
- 有些特殊的字符不能直接在网页中直接显示
- 例如:
表示空格,<
表示<
,>
表示>
7. 背景设置(CSS替代方案)
背景颜色设置示例:
<!-- 使用body的bgcolor属性设置网页背景色(旧式方法) -->
<body bgcolor="#E6E6FA">
<h1>Hello world!</h1>
<p><a href="https://www.w3school.com.cn ">访问 W3School.com.cn!</a></p>
</body>
现代CSS替代方案:
<html>
<head>
<style>
/* 使用CSS设置文档的背景颜色 */
body {
background-color: #E6E6FA; /* 淡紫色背景 */
}
</style>
</head>
<body>
<h1>Hello world!</h1>
<p><a href="https://www.w3school.com.cn ">访问 W3School.com.cn!</a></p>
</body>
</html>
显示效果:
- 页面背景显示为淡紫色(#E6E6FA)
- 包含一个标题 “Hello world!”
- 包含一个指向W3School的链接文本 “访问 W3School.com.cn!”
向文档添加背景图像(使用 CSS):
<html>
<head>
<style>
body {
background-image: url(w3s.png);
}
</style>
</head>
<body>
<h1>Hello world!</h1>
<p><a href="https://www.w3school.com.cn ">访问 W3School.com.cn!</a></p>
</body>
</html>
学习资源
W3School - 领先的 Web 技术教程 - 全部免费
在 W3School,你可以找到你所需要的所有的网站建设教程。
从基础的 HTML 到 CSS,乃至进阶的 XML、SQL、JS、PHP 和 Java。
从左侧的菜单选择你需要的教程!