传统JDBC的缺点

1. 繁琐的样本代码

每次执行一条sql,无论sql简单还复杂,都需要:加载驱动、创建连接、遍历结果集、关闭资源等流程。这会导致核心逻辑淹没在大量的支撑代码当中。

示例:比如即使是查询一个用户名,也要写如下的代码:

ini 复制代码
public static void main(String[] args) throws ClassNotFoundException {
    Class.forName("com.mysql.jdbc.Driver");
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        connection = DriverManager.getConnection("jdbc:mysql://192.168.1.1:3306/ruoyi?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&useInformationSchema=true", "root", "123456");
        preparedStatement = connection.prepareStatement("select user_name from sys_user where user_id=1");
        resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            System.out.println(resultSet.getString("user_name"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }   finally {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. 资源释放容易泄露

JDBC要求开发者手动关闭ResultSet、PreparedStatement、Connection资源。在复杂的逻辑中(比如多重嵌套的if-else),容易遗漏某个资源的关闭,导致数据库连接池用尽,最终程序崩溃。

3. 硬编码SQL导致代码维护困难

JDBC将sql直接写在java类中,当业务变更导致表结构或查询语句变更时,需要改java代码并重编译整个项目。同时这种字符串拼接的方式,开发体验非常差,非常容易将sql拼写错误。

4. 参数设置及其不灵活

JDBC变量的占位符是?,开发人员必须手动通过索引来设置参数(ps.setLong(0,1))。当sql

参数很多时,数清楚每个占位符对应的变量非常麻烦。

vbscript 复制代码
// 这种代码极其容易把位置指错
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.setString(3, user.getEmail());
// ... 想象一下有 30 个参数的情况

5. 结果集映射手动转换

JDBC返回的结果集是ResultSet对象。开发人员需要遍历结果集,并一个一个字段的取数据,组装到POJO对象中。

ini 复制代码
public class JdbcUtils {

    @Data
    static class User {
        private Long userId;
        private String userName;
        private String password;
        private Integer age;
    }

    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = DriverManager.getConnection("jdbc:mysql://192.168.1.1:3306/ruoyi?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowMultiQueries=true&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&useInformationSchema=true", "root", "123456");
            preparedStatement = connection.prepareStatement("select * from sys_user where user_id=?");
            preparedStatement.setLong(1, 1);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                User user = new User();
                user.setUserId(resultSet.getLong("user_id"));
                user.setUserName(resultSet.getString("user_name"));
                user.setPassword(resultSet.getString("password"));
                user.setAge(resultSet.getInt("age"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }   finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                if (connection != null) {
                    connection.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

6. 异常处理太笼统

JDBC抛出的异常基本都是SQLException,无论是语法错误、连接超时、违反唯一键约束,还是数据库挂了,抛出的都是同一个异常。很难通过这个异常定位出更具体的问题。

7. 缺乏事务管理的便捷性

在 JDBC 中处理事务需要手动调用 conn.setAutoCommit(false)conn.commit() / conn.rollback()。当涉及跨多个 Service 调用的复杂事务时,手动传递 Connection 对象会让代码耦合度爆炸。

为了解决这些痛点,业界提供了一些解决方案:

  • apache DbUtils/Spring JdbcTemplate:主要解决样板代码和资源关闭问题
  • Mybatis:解决了SQL硬编码和结果集映射的问题
  • Hibernate、spring data jpa:通过ORM对象映射,让我们彻底摆脱编写简单SQL。
相关推荐
妙码生花10 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十五):优化细节、网络请求封装
前端·后端·ai编程
用户67570498850211 小时前
Go 语言里判断字符串为空,90% 的人都写错了!
后端·go
用户67570498850211 小时前
Go 进阶必修:90% 的人都没用对的“表驱动法”
后端·go
小兔崽子去哪了11 小时前
Java 生成二维码解决方案
java·后端
苍何11 小时前
懂事的 Agent 已经开始自己看屏幕干活了,效率起飞!
后端
掘金码甲哥12 小时前
1分钟买不了吃亏系列: nginx动态域名解析
后端
神奇小汤圆12 小时前
2026大厂Java岗面试记录:八股+场景+项目+AI,一文讲透快速上岸路径(含答案)
后端
神奇小汤圆12 小时前
我说MySQL每张表最好不超过2000万条数据,面试官让我回去等通知?
后端
HuanYu12 小时前
JDK实现动态代理
后端
袋鱼不重12 小时前
解决 Web 端图片预览与下载颜色不一致的一种工程方案
前端·后端