大家好,欢迎来到IT知识分享网。
哈喽 大家好!
我是老陈,在学这节课之前,如果你对数据库不了解,建议你先看《程序员必修数据库》合集。操作数据库,就像人通过笔记本(数据库)记录信息,先找到笔记本(连接数据库),再按格式写内容(创建表结构),之后随时翻看、修改、补充(增删改查)。
我们以SQLite为例,学习Java是如何操作数据库的。首先,你需要去下载sqlite-jdbc开发包并导入到工程里。
37.1 创建数据库
通过JDBC实现与SQLite的交互,核心是通过驱动程序建立连接并执行数据库操作。SQLiteFeatures类包含创建数据库文件、连接管理及异常处理等核心功能。
package com.sqlite.demo; import java.sql.*; import java.io.File; / * @author 今日头条:老陈说编程 * 使用Java的JDBC API连接SQLite数据库, * 包含数据库文件自动创建、连接管理和基本异常处理功能。 * 使用说明: * 1. 确保项目中包含SQLite JDBC驱动依赖 * 2. 运行程序后将在当前目录生成crm.db文件 * 3. 可通过修改dbPath变量指定其他数据库路径 * 异常处理: * - 数据库连接失败时捕获SQLException并输出错误信息 * - 处理其他可能的运行时异常并提供堆栈跟踪 */ public class SQLiteFeatures { public static void main(String[] args) { // 定义SQLite数据库文件路径 String dbPath = "crm.db"; // 创建文件对象用于检查数据库文件状态 File dbFile = new File(dbPath); try { // 检查数据库文件是否存在 if (!dbFile.exists()) { System.out.println("数据库文件不存在,将自动创建:" + dbFile.getAbsolutePath()); // SQLite会在首次连接时自动创建不存在的数据库文件 } // 使用try-with-resources自动关闭数据库连接 try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + dbPath)) { System.out.println("成功连接到SQLite数据库"); // 连接成功后再次检查文件状态并输出信息 if (dbFile.exists()) { System.out.println("数据库文件大小:" + dbFile.length() + " 字节"); } // 可在此处添加更多数据库操作代码 } catch (SQLException e) { // 捕获SQL异常并输出错误信息和堆栈跟踪 System.out.println("数据库连接错误:" + e.getMessage()); e.printStackTrace(); } } catch (Exception e) { // 捕获其他未知异常 System.out.println("发生未知错误:" + e.getMessage()); e.printStackTrace(); } } }
37.2 创建表并插入数据
SQLiteBasicOps类使用JDBC在 SQLite 中创建具有自增主键和自动时间戳功能的数据表,搞懂资源自动管理和 SQL 异常处理机制。
package com.sqlite.demo; import java.sql.*; / * @author 今日头条:老陈说编程 * 使用Java的JDBC API连接SQLite数据库 * 创建表,并采用了try-with-resources自动关闭资源 */ public class SQLiteBasicOps { public static void main(String[] args) { // 数据库文件路径 String dbPath = "crm.db"; // 使用try-with-resources自动关闭Connection连接 try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + dbPath)) { System.out.println("成功连接到SQLite数据库:" + dbPath); // 1. 创建用户表,包含自增主键和创建时间戳 String createTableSQL = "CREATE TABLE IF NOT EXISTS users (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "username TEXT NOT NULL," + "email INTEGER UNIQUE," + "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"; // 使用try-with-resources自动关闭Statement try (Statement stmt = conn.createStatement()) { stmt.execute(createTableSQL); System.out.println("用户表创建成功"); } } catch (SQLException e) { // 捕获SQL异常并打印错误信息和堆栈跟踪 System.out.println("数据库操作错误:" + e.getMessage()); e.printStackTrace(); } } }
37.3 数据操作:增删改查
旁白: SQLiteCRUD类通过 JDBC 操作 SQLite 数据库的完整增删改查流程,采用面向对象设计封装数据实体,并使用预编译语句防止 SQL 注入。
package com.sqlite.demo; import java.sql.*; import java.util.ArrayList; import java.util.List; / * @author 今日头条:老陈说编程 * SQLite数据库的完整CRUD操作 * 包含用户对象定义和对用户表的增删改查方法 * 使用了预编译语句防止SQL注入,并通过try-with-resources自动处理资源关闭 */ public class SQLiteCRUD { / * 用户实体类,封装用户信息 */ static class Users { private int id; // 用户ID,对应数据库主键 private String username; // 用户姓名 private String email; //邮件地址 // Getter和Setter方法 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } // 重写toString方法,便于打印用户信息 @Override public String toString() { return "Users{id=" + id + ", username='" + username + "', email=" + email + "}"; } } public static void main(String[] args) { String dbPath = "crm.db"; // 数据库文件路径 // 使用try-with-resources自动关闭数据库连接 try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + dbPath)) { // 确保数据库连接成功 System.out.println("成功连接到SQLite数据库"); // 1. 查询所有用户记录 List<Users> userList = queryAllUsers(conn); System.out.println("查询到" + userList.size() + "个用户:"); userList.forEach(System.out::println); // 2. 插入新用户并返回自动生成的ID int newId = insertUser(conn, "王五", ""); System.out.println("插入新用户,ID:" + newId); // 3. 更新指定用户的邮件 updateUserEmail(conn, newId, ""); System.out.println("更新用户邮箱为"); // 4. 根据ID删除用户 deleteUser(conn, 1); // 删除ID=1的用户 System.out.println("删除ID=1的用户"); // 5. 再次查询验证操作结果 userList = queryAllUsers(conn); System.out.println("最终用户列表:"); userList.forEach(System.out::println); } catch (SQLException e) { // 异常处理:打印SQL异常堆栈信息 System.err.println("SQL操作错误: " + e.getMessage()); e.printStackTrace(); } } / * 查询所有用户记录 * * @param conn 数据库连接 * @return 用户列表 * @throws SQLException SQL操作异常 */ private static List<Users> queryAllUsers(Connection conn) throws SQLException { List<Users> list = new ArrayList<>(); String sql = "SELECT id, username, email FROM Users ORDER BY id"; // 使用try-with-resources自动关闭Statement和ResultSet try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { // 遍历结果集,将每条记录转换为Users对象 while (rs.next()) { Users user = new Users(); user.setId(rs.getInt("id")); // 获取ID字段 user.setUsername(rs.getString("username")); // 获取姓名字段 user.setEmail(rs.getString("email")); // 获取邮箱 list.add(user); } } return list; } / * 插入新用户记录 * * @param conn 数据库连接 * @param name 用户名 * @param email 邮件地址 * @return 新记录的ID,失败时返回-1 * @throws SQLException SQL操作异常 */ private static int insertUser(Connection conn, String name, String email) throws SQLException { String sql = "INSERT INTO Users(username, email) VALUES (?, ?)"; // 使用预编译语句并要求返回生成的键 try (PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { pstmt.setString(1, name); // 设置第一个参数 pstmt.setString(2, email); // 设置第二个参数 pstmt.executeUpdate(); // 获取自动生成的ID try (ResultSet rs = pstmt.getGeneratedKeys()) { if (rs.next()) { return rs.getInt(1); // 返回自动生成的主键值 } } } return -1; // 插入失败时返回-1 } / * 更新用户年邮箱 * * @param conn 数据库连接 * @param id 用户ID * @param email 新邮箱 * @throws SQLException SQL操作异常 */ private static void updateUserEmail(Connection conn, int id, String email) throws SQLException { String sql = "UPDATE Users SET email = ? WHERE id = ?"; // 使用预编译语句防止SQL注入 try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, email); // 设置邮箱 pstmt.setInt(2, id); // 设置ID参数 pstmt.executeUpdate(); } } / * 根据ID删除用户 * * @param conn 数据库连接 * @param id 用户ID * @throws SQLException SQL操作异常 */ private static void deleteUser(Connection conn, int id) throws SQLException { String sql = "DELETE FROM Users WHERE id = ?"; // 使用预编译语句执行删除操作 try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, id); // 设置ID参数 pstmt.executeUpdate(); } } }
37.4 事务处理:确保数据一致性
旁白: 事务是数据库操作的基本单元,确保一组 SQL 操作要么全部成功执行,要么在发生错误时全部回滚,维持数据的一致性。
package com.sqlite.demo; import java.sql.*; / * @author 今日头条:老陈说编程 * SQLite数据库事务处理 * 尝试向Users表中顺序插入两条用户记录, * 由于使用固定ID(1),第二条插入会触发唯一约束冲突, * 从而导致整个事务回滚。 */ public class SQLiteTransaction { / * 程序入口点 * * @param args 命令行参数(未使用) */ public static void main(String[] args) { // 数据库文件路径 String dbPath = "crm.db"; // 使用try-with-resources自动关闭数据库连接 try (Connection conn = DriverManager.getConnection("jdbc:sqlite:" + dbPath)) { // 关闭自动提交,开启手动事务管理 conn.setAutoCommit(false); System.out.println("开始事务操作"); try { // 步骤1: 插入用户A(赵六)到Users表 insertUser(conn, "赵六", ""); System.out.println("插入用户A"); // 步骤2: 插入用户B(钱七),故意使用重复ID(1)引发约束冲突 insertUser(conn, "钱七", ""); System.out.println("插入用户B"); // 若上一步抛异常,此句不会执行 // 所有操作成功,提交事务 conn.commit(); System.out.println("事务提交成功"); } catch (SQLException e) { // 捕获SQL异常,回滚事务到初始状态 conn.rollback(); System.out.println("事务回滚:" + e.getMessage()); } finally { // 恢复自动提交模式(默认行为) conn.setAutoCommit(true); } } catch (SQLException e) { // 处理数据库连接异常 e.printStackTrace(); } } / * 向Users表插入用户记录(故意使用固定ID=1制造唯一约束冲突) * * @param conn 数据库连接 * @param username 用户姓名 * @param email 邮箱 * @throws SQLException 执行SQL语句异常 */ private static void insertUser(Connection conn, String username, String email) throws SQLException { // 注意:固定ID=1会导致多次插入时违反唯一约束 String sql = "INSERT INTO Users (id, username, email) VALUES (1, ?, ?)"; // 使用预编译语句防止SQL注入 try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, username); // 设置第一个占位符(姓名) pstmt.setString(2, email); // 设置第二个占位符(邮箱) pstmt.executeUpdate(); // 执行插入操作 } } }
总结SQLite的适用场景
移动应用本地存储:Android、iOS 和鸿蒙应用的本地数据持久化;
桌面工具数据存储:轻量级桌面应用的数据存储,如笔记和待办事项软件;
嵌入式系统:物联网设备、智能家居的本地数据记录;
下期将讲解网络请求,记得点赞关注,评论区留下你遇到的SQLite 操作问题,我们一起解决!
#数据库##sql##程序员##计算机##热门##热搜##今日头条#
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/185201.html