杰瑞科技汇

Java数据库insert操作如何高效执行?

核心步骤(所有方法通用)

无论使用哪种技术,向数据库插入数据的逻辑都遵循以下基本步骤:

Java数据库insert操作如何高效执行?-图1
(图片来源网络,侵删)
  1. 加载驱动:告诉 JVM 使用哪个数据库的 JDBC 驱动程序。(对于较新的 JDBC 版本,此步骤通常是可选的)。
  2. 建立连接:使用 JDBC URL、用户名和密码创建与数据库的连接对象。
  3. 创建语句:通过连接对象创建一个 StatementPreparedStatement 对象,用于执行 SQL 命令。
  4. 执行 SQL:调用 executeUpdate() 方法来执行 INSERT 语句。
  5. 处理结果:检查 executeUpdate() 返回的整数,表示受影响的行数。
  6. 关闭资源非常重要! 按照后开先关的原则,依次关闭 ResultSetStatementConnection,以释放数据库资源。

使用 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
    }
}

优点

Java数据库insert操作如何高效执行?-图2
(图片来源网络,侵删)
  • 防止 SQL 注入:参数是作为数据处理,而不是作为 SQL 命令的一部分。
  • 性能更高PreparedStatement 可以被预编译和缓存。
  • 代码更清晰:避免了字符串拼接的混乱。

使用 JPA / Hibernate(面向对象)

如果你在开发企业级应用,通常会使用 ORM(对象关系映射)框架,如 Hibernate(JPA 的实现),你不再需要写 SQL,而是直接操作 Java 对象,框架会自动将其转换为 SQL 并执行。

准备工作

  1. 添加依赖 (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>
  2. 创建实体类

    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; }
    }
  3. 配置文件 (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 之间,更灵活)等现代框架。
分享:
扫描分享到社交APP
上一篇
下一篇