当前位置: 首页 > news >正文

从零开始学JAVAWeb-5


 ​​一、JDBC 架构深度解析​

1. ​​驱动加载底层原理​
  • ​SPI 机制(Service Provider Interface)​
    JDBC 4.0+ 通过 META-INF/services/java.sql.Driver 文件自动注册驱动,无需 Class.forName()
    # 文件内容(MySQL 驱动)
    com.mysql.cj.jdbc.Driver
  • ​多数据库支持​​:更换数据库只需修改连接 URL 和驱动实现(如 Oracle:jdbc:oracle:thin:@localhost:1521:ORCL)。
2. ​​核心接口协作流程​
graph LRA[DriverManager] --> B[Driver]B --> C[Connection]C --> D[Statement]D --> E[ResultSet]

✅ ​​关键点​​:

  • Connection 管理事务和语句池
  • PreparedStatement 继承 Statement,添加预编译能力

 ​​二、企业级开发实战进阶​

1. ​​安全防护:SQL 注入防御​
  • ​预编译原理​​:
    String sql = "SELECT * FROM user WHERE username=? AND password=?";
    PreparedStatement ps = conn.prepareStatement(sql);  // 此处完成SQL解析
    ps.setString(1, name);  // 参数视为纯数据,非代码片段
    即使参数含 ' OR '1'='1,数据库仅按字符串处理,不会改变 SQL 语义。
2. ​​事务控制高级策略​
​隔离级别​​脏读​​不可重复读​​幻读​​适用场景​
TRANSACTION_READ_UNCOMMITTED低一致性要求
TRANSACTION_READ_COMMITTED默认(Oracle)
TRANSACTION_REPEATABLE_READ​MySQL 默认​
TRANSACTION_SERIALIZABLE强一致性(银行转账)

​代码实现​​:

conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
conn.setAutoCommit(false);
try {transferFunds(conn, from, to, amount); // 转账逻辑conn.commit();
} catch (SQLException e) {conn.rollback();  // 失败回滚
}
3. ​​批处理性能优化​
  • ​对比单次提交​​:
    // 传统方式(慢)
    for (User user : users) {ps.setString(1, user.getName());ps.executeUpdate();  // 每次提交产生网络IO
    }// 批处理(快5-20倍)
    for (User user : users) {ps.setString(1, user.getName());ps.addBatch();  // 缓存操作
    }
    int[] results = ps.executeBatch();  // 单次提交
    实测:插入 10,000 条记录,批处理耗时 ≈ 1.5s,单次提交耗时 ≈ 30s。

 ​​三、连接池深度调优(HikariCP)​

1. ​​关键参数配置​
​参数​​推荐值​​作用​
maximumPoolSizeCPU核心数 * 2 + 1避免过度竞争
minimumIdle同最大连接数防止突发流量
connectionTimeout3000 ms超时快速失败
idleTimeout600000 ms释放闲置连接
maxLifetime1800000 ms强制刷新连接(避免数据库侧超时)
2. ​​监控指标​
HikariPool pool = (HikariPool) dataSource.getHikariPoolMXBean();
System.out.println("活跃连接: " + pool.getActiveConnections());
System.out.println("空闲连接: " + pool.getIdleConnections());

 ​​四、ORM 演进与 MyBatis 衔接​

1. ​​JDBC 痛点 vs ORM 优势​
​对比维度​​原生 JDBC​​MyBatis​
​SQL 编写​硬编码在 Java 中XML/注解分离,动态 SQL
​结果集映射​手动遍历 ResultSet自动映射到 JavaBean
​缓存支持​需手动实现一级/二级缓存内置
​事务管理​底层 API 控制声明式事务支持
2. ​​MyBatis 核心组件​
graph TBA[SqlSessionFactory] --> B[SqlSession]B --> C[Executor]C --> D[MappedStatement]D --> E[SQL 解析]E --> F[结果映射]

 ​​五、安全与异常处理规范​

1. ​​防御性编程实践​
  • ​资源关闭顺序​​:
    try (ResultSet rs = ps.executeQuery();PreparedStatement ps = conn.prepareStatement(sql);Connection conn = dataSource.getConnection()) {// 操作代码
    }  // 自动关闭(顺序:rs → ps → conn)
  • ​SQL 异常分类处理​​:
    ​异常类型​​处理方案​
    SQLSyntaxErrorException日志报警 + 返回友好提示
    SQLTimeoutException重试机制或异步处理
    DataIntegrityViolation事务回滚 + 数据校验增强
2. ​​敏感数据防护​
  • ​加密存储​​:
    // 密码加密存储
    String encryptedPwd = BCrypt.hashpw(rawPassword, BCrypt.gensalt());
    ps.setString(2, encryptedPwd);
  • ​日志脱敏​​:
    logger.info("用户 {} 登录", mask(username));  // mask() 实现数据掩码

 ​​六、性能压测对比报告​

​场景​​QPS(单机 Tomcat)​​平均响应时间​​优化建议​
原生 JDBC(无池)12085 ms​必须使用连接池​
HikariCP(默认配置)210015 ms-
HikariCP + 批处理95005 ms适合批量导入场景
MyBatis(缓存关闭)180018 ms开启二级缓存提升读性能

💡 ​​结论​​:连接池 + 预编译 + 批处理 = 性能基准线,ORM 框架解决开发效率问题。


 ​​七、深度思考题​

  1. ​预编译为何能防注入?​

    预编译将 SQL 结构(命令)与数据分离,数据库引擎先解析命令模板,再将参数作为纯数据处理,类似函数参数传递。

  2. ​连接池连接泄漏如何定位?​

    方案:

    • 启用 leakDetectionThreshold(HikariCP)
    • 监控 SELECT * FROM information_schema.PROCESSLIST(数据库侧)
  3. ​高并发下事务隔离级别如何选型?​

    读多写少选 READ_COMMITTED(避免幻读锁开销),写多读少选 REPEATABLE_READ(保证数据一致性)。


 ​​明日预告:Day 6 - MVC 分层架构重构​

  • ​分层规范​​:
    src/
    ├── controller  # 请求路由(Servlet)
    ├── service     # 业务逻辑(事务控制)
    ├── dao         # 数据访问(JDBC/MyBatis)
    └── model       # 实体类
  • ​重构重点​​:
    • 抽离 SQL 到 DAO 层
    • 服务层封装事务边界
    • Controller 纯化(仅处理 HTTP 交互)

​学习建议​​:

  1. 尝试用 HikariCP 替换今日示例中的 DriverManager
  2. 模拟转账并发场景(A 同时向 B、C 转账),验证事务隔离级别影响

“JDBC 是数据操作的基石,安全与性能如同鸟之双翼。” 今日攻克底层细节,明日迈向架构设计!


http://www.dtcms.com/a/326813.html

相关文章:

  • 腾讯云Edgeone限时免费
  • for循环详解与实战技巧
  • Edit Distance
  • 传统制造业减人不减效:一线用工优化的3个投入方向,用对工具比盲目裁员更关键
  • 对抗样本攻击检测与防御
  • 车载软件架构 --- 车辆量产后怎么刷写Flash Bootloader
  • BLE ADV
  • special topic 9 (2) and 1011(1)division one
  • 深入解析Windows系统下UDP绑定失败的原理与系统级解决方案
  • 数据库三范式入门教程
  • Windows11 PowerShell CMD
  • Ascend DrivingSDK 中的 modulated_deform_conv2d(一)
  • GESP2023年9月认证C++一级( 第三部分编程题(1)买文具)
  • MATLAB实现遗传算法求解路网路由问题
  • PTE之路--03文
  • 【08-神经网络介绍】
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十三天-投递简历-[特殊字符][特殊字符]
  • Linux驱动学习day27天(USB驱动理论部分)
  • SSR-code 项目复刻与3D模型生成实现
  • nomachine的安装和使用
  • 华清远见25072班C语言学习day6
  • 操作系统1.5:操作系统引导
  • 101. 孤岛的总面积
  • 下一代防火墙组网
  • 晓知识: 动态代理与静态代理的区别
  • Android模块化架构深度解析:从设计到实践
  • 强联通分量(重制版)
  • 环境配置-拉取NVIDIA Docker镜像时出现401Unauthorized错误
  • 数据填报是什么?数据填报工具有哪些?
  • 黑马程序员mysql基础篇笔记