核心步骤(所有方法通用)
无论使用哪种技术,向数据库插入数据的逻辑都遵循以下基本步骤:

- 加载驱动:告诉 JVM 使用哪个数据库的 JDBC 驱动程序。(对于较新的 JDBC 版本,此步骤通常是可选的)。
- 建立连接:使用 JDBC URL、用户名和密码创建与数据库的连接对象。
- 创建语句:通过连接对象创建一个
Statement或PreparedStatement对象,用于执行 SQL 命令。 - 执行 SQL:调用
executeUpdate()方法来执行INSERT语句。 - 处理结果:检查
executeUpdate()返回的整数,表示受影响的行数。 - 关闭资源:非常重要! 按照后开先关的原则,依次关闭
ResultSet、Statement和Connection,以释放数据库资源。
使用 Statement(不推荐用于生产环境)
这是最直接的方法,通过字符串拼接来构建 SQL 语句。这种方法有巨大的 SQL 注入风险,仅用于学习或简单的、固定的脚本。
示例代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
public class JdbcInsertExample {
// 数据库连接信息
private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
private static final String USER = "your_username";
private static final String PASS = "your_password";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
// 1. 加载驱动 (对于 MySQL 8.0+,可以省略此步)
// Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3. 创建 Statement 对象
System.out.println("Creating statement...");
stmt = conn.createStatement();
// 4. 准备 SQL 语句
// !!! 危险: 直接拼接字符串,极易发生 SQL 注入 !!!
String sql = "INSERT INTO users (name, email, age) " +
"VALUES ('John Doe', 'john.doe@example.com', 30)";
// 5. 执行 SQL
int rowsAffected = stmt.executeUpdate(sql);
System.out.println(rowsAffected + " row(s) inserted.");
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 6. 关闭资源
// 确保在任何情况下(try 或 catch)都会执行关闭操作
try {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
缺点:
- SQL 注入风险:如果用户输入被拼接到 SQL 中,恶意用户可以破坏数据库。
- 性能差:每次执行,数据库都需要重新解析和编译 SQL 语句。
- 代码可读性差:处理特殊字符(如单引号)时非常麻烦。
使用 PreparedStatement(推荐)
这是标准且安全的方法,它使用参数化查询( 作为占位符),可以有效防止 SQL 注入,并且数据库可以缓存预编译的语句,性能更好。
示例代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcPreparedStatementInsertExample {
private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
private static final String USER = "your_username";
private static final String PASS = "your_password";
public static void main(String[] args) {
// 使用 try-with-resources 语句,可以自动关闭资源,更安全简洁
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)")) {
// 1. 设置参数 (索引从 1 开始)
pstmt.setString(1, "Jane Smith"); // 第一个 ? 替换为 'Jane Smith'
pstmt.setString(2, "jane.smith@example.com"); // 第二个 ? 替换为 'jane.smith@example.com'
pstmt.setInt(3, 28); // 第三个 ? 替换为 28
// 2. 执行 SQL
int rowsAffected = pstmt.executeUpdate();
System.out.println(rowsAffected + " row(s) inserted.");
} catch (SQLException e) {
e.printStackTrace();
}
// try-with-resources 会自动在这里关闭 conn 和 pstmt
}
}
优点:

- 防止 SQL 注入:参数是作为数据处理,而不是作为 SQL 命令的一部分。
- 性能更高:
PreparedStatement可以被预编译和缓存。 - 代码更清晰:避免了字符串拼接的混乱。
使用 JPA / Hibernate(面向对象)
如果你在开发企业级应用,通常会使用 ORM(对象关系映射)框架,如 Hibernate(JPA 的实现),你不再需要写 SQL,而是直接操作 Java 对象,框架会自动将其转换为 SQL 并执行。
准备工作
-
添加依赖 (Maven):
<!-- JPA API --> <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.1.0</version> </dependency> <!-- Hibernate 实现 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</groupId> <version>6.1.7.Final</version> </dependency> <!-- 数据库驱动 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> -
创建实体类
import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @Entity // 标记这是一个 JPA 实体,对应数据库中的一张表 public class User { @Id // 标记为主键 @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键自增 private Long id; private String name; private String email; private int age; // 必须有一个无参构造器 public User() {} // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } -
配置文件 (
persistence.xml)<persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="myPersistenceUnit"> <provider>org.hibernate.orm.HibernatePersistenceProvider</provider> <properties> <!-- 数据库连接信息 --> <property name="jakarta.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/> <property name="jakarta.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/your_database"/> <property name="jakarta.persistence.jdbc.user" value="your_username"/> <property name="jakarta.persistence.jdbc.password" value="your_password"/> <!-- Hibernate 特定配置 --> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <!-- 自动更新表结构 --> <property name="hibernate.show_sql" value="true"/> <!-- 在控制台打印 SQL --> </properties> </persistence-unit> </persistence>
示例代码
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class HibernateInsertExample {
public static void main(String[] args) {
// 1. 创建 EntityManagerFactory (通常在应用启动时创建一次)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit");
// 2. 创建 EntityManager
EntityManager em = emf.createEntityManager();
try {
// 3. 开始事务
em.getTransaction().begin();
// 4. 创建并设置 User 对象
User user = new User();
user.setName("Peter Jones");
user.setEmail("peter.jones@example.com");
user.setAge(45);
// 5. 持久化对象 (插入数据)
em.persist(user); // 此时数据还未真正写入数据库
// 6. 提交事务 (在提交时,SQL 语句才会被执行)
em.getTransaction().commit();
System.out.println("User inserted with ID: " + user.getId());
} catch (Exception e) {
// 如果发生错误,回滚事务
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
e.printStackTrace();
} finally {
// 7. 关闭资源
em.close();
emf.close();
}
}
}
优点:
- 面向对象:代码更符合 Java 思想,易于维护。
- 减少样板代码:无需手动编写和管理 SQL。
- 数据库无关性:更换数据库(如从 MySQL 换到 PostgreSQL)通常只需修改配置文件。
- 高级特性:支持缓存、延迟加载、关联映射等复杂功能。
总结与选择
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
Statement |
简单直接 | 不安全(SQL注入),性能差,代码混乱 | 学习 JDBC 基本概念,或一次性、无用户输入的脚本。 |
PreparedStatement |
安全(防注入),性能好,代码清晰 | 需要手动设置参数 | 绝大多数 JDBC 开发场景的首选。 |
| JPA / Hibernate | 面向对象,代码优雅,减少 SQL,数据库无关 | 学习曲线陡峭,性能开销(通常可忽略),配置复杂 | 企业级 Java 应用(如 Spring Boot 项目),业务逻辑复杂的项目。 |
建议:
- 对于初学者或小型项目,熟练掌握
PreparedStatement是必备技能。 - 对于任何正式的、需要长期维护的项目,强烈推荐使用 Spring Data JPA(它是对 JPA/Hibernate 的进一步封装)或 MyBatis(介于 JDBC 和 JPA 之间,更灵活)等现代框架。
