当前位置:首页 > 数据库 > 正文

java中怎么使用数据库

在Java中使用数据库需引入JDBC驱动,加载驱动类,建立连接,创建Statement对象,执行SQL语句,处理ResultSet结果集,最后

核心前置条件

1 技术栈组成

组件 作用 典型实现
JDBC API Java标准接口,统一访问关系型数据库 java.sql
驱动管理器 动态加载数据库厂商提供的JDBC驱动 Class.forName()
数据库驱动 实现JDBC接口的具体类(不同数据库需对应驱动) MySQL Connector/J
物理连接 通过网络协议与数据库服务器建立TCP长连接 DriverManager.getConnection()
SQL引擎 解析并执行SQL语句,返回结果集 Database Server内部模块

2 环境准备清单

开发工具: IntelliJ IDEA/Eclipse + Maven/Gradle
依赖配置 (以MySQL为例):

<!-pom.xml -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version> <!-根据实际版本调整 -->
</dependency>

注意: 不同数据库驱动包名称不同(Oracle为ojdbcX.jar,PostgreSQL为postgresql-XX.jar)

java中怎么使用数据库  第1张


标准开发流程详解

1 七步标准操作法

序号 步骤 关键代码示例 说明
1 加载数据库驱动 Class.forName("com.mysql.cj.jdbc.Driver") 触发静态初始化块注册驱动到DriverManager
2 建立数据库连接 DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "password") URL格式:协议://主机:端口/数据库名
3 创建执行器对象 Connection con = ...;<br>Statement stmt = con.createStatement(); 三种执行器类型:Statement/PreparedStatement/CallableStatement
4 执行SQL语句 ResultSet rs = stmt.executeQuery("SELECT FROM users"); executeQuery()用于查询,executeUpdate()用于DML/DDL
5 处理结果集 while(rs.next()){ System.out.println(rs.getString("username")); } 通过游标逐行读取,列索引从1开始/列名直接获取
6 事务控制 con.setAutoCommit(false);<br>// 多条SQL后<br>con.commit(); 默认自动提交,显式事务需关闭自动提交+手动提交/回滚
7 资源释放 rs.close();<br>stmt.close();<br>con.close(); 逆向顺序关闭,建议使用try-with-resources自动管理

2 完整代码演示(带注释)

import java.sql.;
public class JdbcDemo {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;
        try {
            // 1. 加载驱动(新版MySQL可省略此步)
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2. 建立连接(URL含时区配置)
            String url = "jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC";
            connection = DriverManager.getConnection(url, "root", "123456");
            // 3. 使用预编译语句防止SQL注入
            String sql = "SELECT id, name, email FROM users WHERE age > ?";
            pstmt = connection.prepareStatement(sql);
            pstmt.setInt(1, 18); // 设置第一个占位符的值
            // 4. 执行查询
            resultSet = pstmt.executeQuery();
            // 5. 处理结果集
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                String email = resultSet.getString("email");
                System.out.printf("ID:%d Name:%s Email:%s%n", id, name, email);
            }
            // 6. 执行更新操作示例
            int affectedRows = pstmt.executeUpdate("UPDATE users SET status=1 WHERE id=100");
            System.out.println("更新了" + affectedRows + "条记录");
        } catch (ClassNotFoundException e) {
            System.err.println("驱动加载失败:" + e.getMessage());
        } catch (SQLException e) {
            System.err.println("数据库操作异常:" + e.getMessage());
            try {
                if (connection != null) connection.rollback(); // 事务回滚
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            // 7. 资源释放(按相反顺序)
            try { if(resultSet != null) resultSet.close(); } catch(SQLException e){}
            try { if(pstmt != null) pstmt.close(); } catch(SQLException e){}
            try { if(connection != null) connection.close(); } catch(SQLException e){}
        }
    }
}

关键要素深度解析

1 三种执行器对比表

特性 Statement PreparedStatement CallableStatement
主要用途 简单SQL执行 带参数的预编译SQL 存储过程调用
SQL注入防护 不安全 参数化查询
执行效率 较低(每次编译) 高(首次编译后缓存)
批处理支持 有限 batchUpdate()
适用场景 一次性简单查询 重复执行的参数化查询 T-SQL/PL/SQL脚本执行

2 连接池优化方案

方案 特点 推荐场景
HikariCP 轻量级高性能,默认最大10个连接 Web应用首选
Druid 监控统计功能强大,支持SQL防火墙 企业级应用
DBCP Tomcat自带,配置简单 小型项目快速集成
C3P0 历史悠久,功能全面 传统项目维护

示例配置(HikariCP):

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version>
</dependency>
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("123456");
config.setMaximumPoolSize(10); // 最大连接数
HikariDataSource ds = new HikariDataSource(config);
Connection connection = ds.getConnection();

高级技巧与注意事项

1 SQL注入防御策略

错误写法:字符串拼接会导致破绽

String sql = "SELECT  FROM users WHERE username='" + userInput + "'"; // 危险!

正确做法:强制使用预编译语句

String sql = "SELECT  FROM users WHERE username=?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setString(1, userInput); // 自动转义特殊字符

2 批量操作优化

String sql = "INSERT INTO logs(content) VALUES(?)";
connection.setAutoCommit(false); // 关闭自动提交提升性能
PreparedStatement pstmt = connection.prepareStatement(sql);
for (String log : logList) {
    pstmt.setString(1, log);
    pstmt.addBatch(); // 加入批处理队列
}
int[] results = pstmt.executeBatch(); // 批量执行
connection.commit(); // 手动提交事务

3 BLOB/CLOB大字段处理

// 读取图片文件
Blob imageBlob = resultSet.getBlob("avatar");
InputStream binaryStream = imageBlob.getBinaryStream();
byte[] bytes = binaryStream.readAllBytes(); // Java 9+方法
// 写入文本文档
Clob documentClob = connection.createClob();
documentClob.setString(1, "大量文本内容");
pstmt.setClob(1, documentClob);

常见错误及解决方案

错误类型 典型表现 根本原因 解决方案
CommunicationsException java.sql.SQLException: No suitable driver found 未加载驱动或驱动不匹配 检查Class.forName()和驱动版本
Access denied SQLSTATE[HY000] [28000] 数据库权限不足 授予用户相应表的操作权限
Latin-1 encoding error 中文乱码 字符集配置不一致 URL添加?characterEncoding=UTF-8
Too many connections Exceeded maximum pool size 连接未及时释放 使用连接池+合理设置超时时间
Lock wait timeout Deadlock found when trying to get lock 事务竞争导致死锁 缩小事务范围+重试机制

相关问答FAQs

Q1: 为什么会出现”No suitable driver found”错误?

A: 此错误通常由以下原因导致:①未正确加载数据库驱动(忘记调用Class.forName());②使用的驱动版本与数据库版本不兼容;③Maven依赖未正确导入,解决方案:检查pom.xml中的驱动依赖版本,确认已添加对应的Class.forName()调用,且驱动JAR包确实存在于classpath中。

Q2: 如何处理数据库连接时的中文乱码问题?

A: 中文乱码的根本原因是字符集编码不一致,解决方法:①在数据库连接URL中添加参数?characterEncoding=UTF-8&useUnicode=true;②确保数据库表的字符集设置为utf8mb4;③在Java代码中统一使用UTF-8编码,例如连接字符串应为:jdbc:mysql://localhost:3306/mydb?characterEncoding=UTF-8&useUnicode=true&serverTimezone=UTC

0