
SQLite 入门
创建者 | ![]() |
---|---|
创建时间 | |
上次编辑者 | ![]() |
上次编辑时间 | |
状态 | 已完成 |
一、为什么我推荐 SQLite
简单就是硬道理。
上图是《程序设计实践II》任务书中的二选一题目,这两个题目都提到推荐使用 MySQL 作为数据库管理系统。
但我认为,对于这类小型项目,使用 MySQL 有如大炮打蚊子、杀鸡用牛刀。对于初学者来说,我更推荐使用 SQLite 作为数据库管理系统,原因有三:
- 配置简单:不需要任何配置,也不需要通过网络端口连接数据库等复杂操作。
- 语法简单:省略了很多用不上的复杂功能,基础语法非常简单。
- 迁移简单:只要目标环境支持且文件完整,可以直接将数据库文件拷贝到另一台电脑上,相当于你给别人发送了一个 Word 文档,对方点击就能打开并查看里面的内容。而 MySQL 需要复杂的迁移操作。
任务书推荐 MySQL 更多是出于未来就业技能培养的考虑。
如果你想快速高效地完成这个项目,并且深刻理解“用合适的工具做合适的事”,那么大胆地使用 SQLite!
如果你想借此机会挑战一下自己,学习和掌握更通用的企业级数据库技术,那么按照任务书的建议去折腾一下 MySQL 也是非常有价值的。
二、SQL?
说了这么多,又是 MySQL 又是 SQLite,它们究竟是什么,为什么作业需要用到它们?
观察 MySQL 和 SQLite 这两个名称,你会发现它们有一个共同点——SQL。
要想了解 MySQL 和 SQLite,我们先从 SQL 说起。
SQL (Structured Query Language),中文全称“结构化查询语言”,日常读作 /ˈsiːkwəl/ 。
它是一种专门设计用来与数据库进行通信的语言规范。
为什么需要数据库?
在上学期的课程设计任务中,我们通过C语言文件IO简单地读写文件。这种操作虽然便利,但就像把所有资料都随意扔进单个抽屉里,当需要查找时,不仅效率低下,还容易把其它资料弄乱。
数据库,就相当于配备了管理员的大图书馆。它将资料分门别类地放好,将需要频繁查看的资料放在最显眼的位置,还有防盗措施……大大提高了资料的查找效率和安全性。
学习了 SQL, 我们就能操控数据库,完成对资料的增、删、查、改等一系列操作。
MySQL 和 SQLite
可能和你猜测的不太一样,虽然 MySQL 和 SQLite 中都有 SQL,但它们并不是语言规范,而是基于 SQL 开发出的软件产品。
打个不太恰当的比喻,MySQL 和 SQLite 就像谷歌浏览器和Edge浏览器,虽然它们的名字不同,软件页面的设计也不同,但它们都使用 Chromium 作为内核。
同样,MySQL 和 SQLite 都遵循了 SQL 标准,所以对于这两个软件,你可以用类似的 SQL 语法操作它们,但它们在功能等方面有显著差异。MySQL 主要针对企业场景以及大型项目,它的操作更复杂,语法也在 SQL 的基础上作了很多更改。而 SQLite 正如它的名字一样:轻量化,同时针对这种小型项目也更加容易配置。
三、安装 SQLite
既然 SQLite 是一个软件,我们就必须先安装再使用。
下面给出 Windows 和macOS 的安装方式:
GUI 是图形化界面,可以方便地查看和编辑数据库文件。

CLI 是命令行界面,使用终端查看和编辑数据库文件。

对于 Windows,建议同时安装 GUI 和 CLI。
而对于 macOS,可以只安装 GUI,因为 macOS 中自带一个较低版本的 CLI。如果有需要,可以通过brew 重新安装。
Windows
- GUI (DB Browser for SQLite)
choco install sqlitebrowser
安装后桌面上会有两个快捷方式,其中一个是 (SQLCipher)。它是 DB Browser for SQLite 的一部分,提供了处理加密 SQLite 数据库的附加功能。
- CLI
choco install sqlite
四、安装驱动
我们还需要一个翻译官。
现在,我们再总结一下需求:
- 我们需要使用数据库帮助我们高效地管理数据。
- 对于数据库文件,它是一种特殊格式的文件,我们无法像编辑 .txt 一样直接打开并修改它。我们需要一个软件来帮助我们编辑数据库文件,这个软件就是 SQLite。
- SQL 是一种语言规范,SQLite 遵循这个语言规范。掌握了 SQL 语法后,我们就可以使用 SQL 命令操控 SQLite 软件。
但是,如何在我们的 Java 程序里使用 SQL 命令呢?
事实上,SQL 命令只能在终端使用。在没有引入翻译官前,我们无法在 Java 代码中直接写 SQL 命令,Java 编译器也看不懂这些命令,只会当成普通的字符串。
我们需要引入一个翻译官,它能接收我们写在 Java 代码写的 SQL 命令,然后去和软件沟通,最终让软件对数据库文件进行操作,完成我们发送的命令。
这个翻译官就是 JDBC 驱动程序规范。
JDBC,全称 Java DataBase Connectivity(Java 数据库连接)。为了更好地理解它的功能,我们将其转换成动词的形式:“Java 连接数据库”。这样看,“翻译官”的角色就很明显了。
JDBC 跟 SQL 一样,它们仅仅是开发者参考的规范,不是可以直接使用的工具。为此,我们需要使用 SQLite-JDBC,它才是“真正的”那个翻译官。
SQLite-JDBC 前面的“SQLite”表明这个驱动程序是专门针对 SQLite 软件的。
前面提到,数据管理软件有很多,虽然它们大部分都基本遵循 SQL 语法,但每个软件的内部设计仍有区别,因此我们需要针对特定软件的驱动。由于我们选择了 SQLite 管理数据库,那么我们就必须选择 SQLite-JDBC 作为驱动程序。
对于安装这个驱动程序,以下有两种不同方法:
我是一个新手…
对Java新手(最简单)
下面这个就是最新版的驱动程序。你也可以去项目的源代码仓库获取 release https://github.com/xerial/sqlite-jdbc
下载并解压完成后,直接将它放在项目的 lib 文件夹内。如果没有 lib 文件夹,则新建一个。
这不是必须的操作,但我们需要培养将文件整齐归纳的习惯。
瞧不起谁?
挑战自己?
使用 Maven 吧!具体操作我就不展开了。
五、SQLite 基本语法
正式开始操作数据库。
不知道你有没有这样的疑惑:
前面我们提到“掌握了 SQL 语法后,我们就可以使用 SQL 命令操控 SQLite 软件“。为什么标题是“SQLite 基本语法”,而不是“SQL 基本语法”?
这些软件仅仅是基本遵守 SQL 的规范。可能在原有的语法上作了改进,可能在原有的语法上作了删减。因此,我们不得不学习针对特定软件的语法。
但别担心,虽然它们仅仅是基本遵守 SQL 的规范,但至少还是遵守了的,语法结构仍然有一定程度相似,日后再使用其他软件如 MySQL 也不会非常困难。
在正式开始前,请确保已经安装好了所有程序。
为了快速上手而不是深入学习,我将直接以代码示例的形式给出,需要自己理解语法结构。
注意:
1️⃣ SQLite 命令【关键字】对大小写不敏感,但部分命令的大写形式和小写形式有所区别。为了便于区分命令与普通字符,对于 SQLite 的命令,最好采用区分大小写的方式(通常为大写)。
2️⃣ 哪里要加分号,哪里要加逗号。
前提
在 SQL 的规范中,我们必须先定义表格的每一列(的结构),然后才能插入每一行(的数据)。
例如:
学号 | 姓名 | 班级 | 成绩 |
---|---|---|---|
1 | 张三 | 一 | 100.0 |
2 | 李四 | 二 | 59.0 |
3 | 王五 | 二 | 91.0 |
下面这种表格定义是不合理的,SQL 也不支持这种定义方式。
学号 | 1 | 2 | 3 |
---|---|---|---|
姓名 | 张三 | 李四 | 王五 |
班级 | 一 | 二 | 二 |
成绩 | 100.0 | 59.0 | 91.0 |
启动 SQLite
- 打开终端
cd
进入指定的目录
- 在终端中输入并回车
sqlite3
为了进行接下来的所有操作,请保证 SQLite 处于启动状态。
创建 / 打开一个数据库
.open DatabaseName.db
DatabaseName
数据库的名称
.db
数据库文件后缀(不需要更改)
如果目录中没有这个文件,将会自动创建;如果存在这个文件,将会打开这个数据库。
为了进行接下来的所有操作,请保证数据库处于打开状态。
在数据库中创建一个表格
一个数据库是由许多互相关联的表格构成的,这里的表格不是什么高大上的概念,就是你平时填表的那种表格。
CREATE TABLE IF NOT EXISTS studentss (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR NOT NULL,
class_name TEXT,
score REAL
);
CREATE TABLE
:新建一个表格
-
students
:以“students”命名这个表格
IF NOT EXISTS
:如果目录中不存在叫“students”的表格
id
,name
,class_name
,score
:定义了表格第0行从左到右每个格的变量名id name class_name score 为什么是第0行?
💡当我们调用基本命令(没有添加筛选条件)显示表格时,上面的变量名实际上是不会显示的。如果我们已经创建了这样的表格并添加了一些数据:
id name class_name score 1 张三 1 100 2 李四 2 59 3 张三 2 91 实际显示为:
1 张三 1 100 2 李四 2 59 3 张三 2 91 称为第0行是为了方便理解,与生活中的表格类似。这样定义实际上代表了每一列的变量名。
VARCHAR
,TEXT
,REAL
:变量对应的数据类型
NOT NULL
:这里的格子不能为空(没有任何值)
PRIMARY KEY
:将这个变量作为主键。主键是每一行唯一的标识符,作用是区别张三id name class_name score 1 张三 1 100.0 2 张三 1 100.0 3 李四 2 59.0
AUTOINCREMENT
:主键的修饰符,表示变量自增当我们插入每一行的数据时,只需要输入类似 “王五, 3, 66“ 的结构。
此时
id
会自动 +1,不需要输入。id name class_name score 1 张三 1 100.0 2 张三 1 100.0 3 李四 2 59.0 4 王五 3 66.0
增加表格数据
在 SQL 的规范中,新添加的每一行数据不能指定插入的位置,只能放在最后一行。
使用CREATE TABLE
新建的表格中没有任何数据(注意下方是第0行,实际不显示)。
id | name | class_name | score |
INSERT INTO students (name, class_name, score)
VALUES ('陈六', '一班', 85.5);
id | name | class_name | score |
1 | 陈六 | 一班 | 85.5 |
INSERT INTO students (name, class_name, score) VALUES
('李四', '一班', 92.0),
('王五', '二班', 76.5),
('赵六', '二班', 95.0),
('胡七', '三班', 98.0);
id | name | class_name | score |
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 92.0 |
3 | 王五 | 二班 | 76.5 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
删除表格数据
DELETE FROM table_name WHERE [condition];
WHERE 不是必须的,但如果没有 WHERE 以及后面的 [condition],整个表格的数据将会被删除,只留下第0行:
id | name | class_name | score |
DELETE FROM
:从…地方删除
table_name
:表格名称
WHERE
:哪里
condition
:满足什么条件。往往是一个表达式。
编成一句话:删除table_name
表格中满足condition
条件的行。
DELETE FROM students WHERE id = 3;
id | name | class_name | score |
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 92.0 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
DELETE FROM students WHERE score < 90;
id | name | class_name | score |
2 | 李四 | 一班 | 92.0 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
DELETE FROM students WHERE class_name = '一班' OR class_name = '二班' ;
id | name | class_name | score |
5 | 胡七 | 三班 | 98.0 |
上面的语句还可以简化
DELETE FROM students WHERE class_name IN ('一班', '二班');
查找表格数据
SELECT * FROM students;
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 92.0 |
3 | 王五 | 二班 | 76.5 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
SELECT name, score FROM students;
陈六 | 85.5 |
李四 | 92.0 |
王五 | 76.5 |
赵六 | 95.0 |
胡七 | 98.0 |
SELECT * FROM students WHERE class_name = '一班';
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 92.0 |
SELECT * FROM students WHERE score > 90;
2 | 李四 | 一班 | 92.0 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
SELECT * FROM students ORDER BY score DESC;
5 | 胡七 | 三班 | 98.0 |
4 | 赵六 | 二班 | 95.0 |
2 | 李四 | 一班 | 92.0 |
1 | 陈六 | 一班 | 85.5 |
3 | 王五 | 二班 | 76.5 |
SELECT * FROM students ORDER BY score DESC LIMIT 2;
5 | 胡七 | 三班 | 98.0 |
4 | 赵六 | 二班 | 95.0 |
修改表格数据
UPDATE students
SET score = 98.5
WHERE name = '李四';
id | name | class_name | score |
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 98.5 |
3 | 王五 | 二班 | 76.5 |
4 | 赵六 | 二班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
UPDATE students
SET class_name = '精英班'
WHERE class_name = '二班';
id | name | class_name | score |
1 | 陈六 | 一班 | 85.5 |
2 | 李四 | 一班 | 98.5 |
3 | 王五 | 精英班 | 76.5 |
4 | 赵六 | 精英班 | 95.0 |
5 | 胡七 | 三班 | 98.0 |
查找数据库中的表格
.table
删除数据库中的表格
DROP TABLE IF EXISTS table_name;
使用此命令时要特别注意,一旦一个表被删除,表中所有信息也将永远丢失。
退出数据库并退出 SQLite
.exit
六、在 Java 中使用 SQLite 命令
马上就要完成了……
以下是一个小小的测试用例。
用于测试刚刚的驱动程序能否运行,以及如何在 Java 中使用 SQLite 命令:
/**
* 导入相关的包,以下这些基本上都是必要的。你还可以根据项目需求导入其它的包
*/
import java.sql.Connection; // 用于建立与数据库的连接
import java.sql.DriverManager; // 用于管理JDBC驱动程序
import java.sql.ResultSet; // 用于存储查询结果
import java.sql.Statement; // 用于执行SQL语句
/**
* SQLite 基础操作示例
*/
public class SQLiteSimple {
public static void main(String[] args) throws Exception {
/***************** 0. 驱动注册 *****************/
// 对于较旧版本的Java,通常需要注册驱动操作
// 我们使用的Java版本较新,Java已经帮我们实现了自动注册
/*1. 与数据库建立连接(打开SQLite,创建/打开数据库)*/
Connection conn = DriverManager.getConnection("jdbc:sqlite:simple.db");
System.out.println("数据库连接成功");
/************ 2. 创建Statement对象 *************/
Statement stmt = conn.createStatement();
/************ 3. 在数据库中创建一个表格 **********/
// executeUpdate是Statement类的一个方法,用于执行数据库的更新操作。
stmt.executeUpdate("DROP TABLE IF EXISTS students"); // 如果该表格存在,先删除它
// 可以看到,在 Java 中都是以字符串的形式使用 SQLite 语句
// 与在终端中使用 SQLite 语句不同,每条语句的末尾不需要加分号,只保留Java本身的分号
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS students (
id INTEGER PRIMARY KEY,
name TEXT,
score INTEGER
)");
System.out.println("创建表格成功");
/*************** 4. 增加表格数据 ***************/
stmt.executeUpdate("INSERT INTO students VALUES (1, '张三', 95)");
stmt.executeUpdate("INSERT INTO students VALUES (2, '李四', 88)");
stmt.executeUpdate("INSERT INTO students VALUES (3, '王五', 73)");
System.out.println("插入数据成功");
/*************** 5. 查询表格数据 ***************/
System.out.println("\n所有学生信息:");
// executeQuery是Statement类的一个方法,用于执行数据库的查询操作。
ResultSet rs = stmt.executeQuery("SELECT * FROM students"); // 将查询到的结果传递给ResultSet
// 可以将ResultSet视为一个完整表格,但这个表格只显示第一行
while (rs.next()) { // 使用.next移动到下一行
int id = rs.getInt("id"); // 将get到的数据存储并打印
String name = rs.getString("name");
int score = rs.getInt("score");
System.out.println(id + "\t" + name + "\t" + score);
}
/*************** 6. 更新表格数据 **************/
stmt.executeUpdate("UPDATE students SET score = 100 WHERE name = '张三'");
System.out.println("\n更新后的张三信息:");
rs = stmt.executeQuery("SELECT * FROM students WHERE name = '张三'");
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t" + rs.getString("name") + "\t" + rs.getInt("score"));
}
/*************** 7. 删除表格数据 **************/
stmt.executeUpdate("DELETE FROM students WHERE name = '王五'");
System.out.println("\n删除王五后的所有学生信息:");
rs = stmt.executeQuery("SELECT * FROM students");
while (rs.next()) {
System.out.println(rs.getInt("id") + "\t" + rs.getString("name") + "\t" + rs.getInt("score"));
}
/**************** 8. 关闭数据库 ***************/
rs.close();
stmt.close();
conn.close();
System.out.println("\n数据库连接已关闭");
}
}
代码写完了,我们该如何运行这个程序?
(VSCode)直接点击右上角运行按钮肯定是不行的,不信你试一下。
以下提供两种运行方法:
www我是一个新手😭…
对于 Java 新手,我们需要通过脚本来运行程序
- 如果你使用 Windows
在项目的根目录创建一个 .bat 文件,输入以下代码
@echo off java -cp .;lib\sqlite-jdbc-3.49.1.0.jar SQLiteSimple pause
怎么运行脚本?
最简单的方法——双击.bat文件
通过终端运行
.\run.bat
- 如果你使用 macOS
在项目的根目录创建一个 .sh 文件,输入以下代码:
#!/bin/sh java -cp .:lib/sqlite-jdbc-3.49.1.0.jar SQLiteSimple
在 shell 中执行脚本:
chmod +x run.sh
sh run.sh
- 如果你使用 Windows
瞧不起我?💢
挑战自己?
打包成 JAR 文件吧!
运行成功后,控制台应该会输出以下内容:
数据库连接成功
创建表成功
插入数据成功
所有学生信息:
1 张三 95
2 李四 88
3 王五 73
更新后的张三信息:
1 张三 100
删除王五后的所有学生信息:
1 张三 100
2 李四 88
数据库连接已关闭
最后解答一个疑惑:
如果我将整个项目拷贝到其它电脑(即使没有安装 SQLite 和 驱动),这个项目也可以运行吗?
答案是:“Write Once, Run Anywhere”(一次编写,到处运行)。