Java连接Oracle数据库实战:从驱动选择到连接池配置全解析

发布时间:2026/8/18 3:16:37

Java连接Oracle数据库实战:从驱动选择到连接池配置全解析
1. 项目概述为什么Java连接Oracle依然是硬核技能如果你是一名Java开发者无论你是刚入行的新人还是工作多年的老手连接数据库这个操作都像是吃饭喝水一样基础。但恰恰是这种基础操作里面藏着无数可以让你在关键时刻“翻车”的细节。尤其是连接像Oracle这样重量级的商业数据库它不像MySQL那样“平易近人”从驱动选择、URL格式到连接池配置每一步都有讲究。网上很多教程要么过于简略只给个代码片段要么版本老旧还在用ojdbc14.jar这种上古神器你照着做大概率连不上。所以今天我就以一个踩过无数坑的老兵身份带你从零开始手把手、无死角地搞定Java连接Oracle数据库这件事。目标很简单让你看完就能动手一次成功并且理解背后的每一个“为什么”。2. 环境准备与核心组件拆解在动手写代码之前把“战场”打扫干净、武器准备妥当是成功的一半。很多人连接失败问题都出在环境上。2.1 Oracle数据库侧的准备首先你得有一个能连上的Oracle数据库实例。无论是公司内网的测试库还是你自己在本机安装的虽然这过程可能比较折腾都需要确认以下几点数据库服务与监听状态Oracle数据库由数据库实例和监听器Listener两部分组成。实例负责处理数据监听器负责接收网络连接。你需要确保两者都已启动。可以通过SQL*Plus登录数据库执行select status from v$instance;查看实例状态应该是OPEN。在服务器命令行执行lsnrctl status查看监听状态。网络可访问性确认你的Java应用所在机器能够通过网络IP和端口访问到Oracle服务器。默认监听端口是1521。可以用telnet 服务器IP 1521简单测试。用户与权限准备好一个有足够权限的数据库用户和密码。对于学习测试可以直接用system用户但生产环境务必使用权限最小化的专用用户。注意很多新手卡在“ORA-12541: TNS: 无监听程序”或“ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务”这类错误。这几乎都是监听配置或服务名问题跟Java代码本身关系不大。务必先确保用SQL*Plus等原生工具能连上。2.2 JDBC驱动选对版本是关键这是Java连接Oracle的核心桥梁也是坑最多的地方。驱动类型Oracle提供了两种主要的JDBC驱动类型Thin驱动和OCI驱动。Thin驱动是纯Java实现轻量级跨平台适用于绝大多数场景也是我们本文使用的。OCI驱动需要本地Oracle客户端性能略高但部署复杂除非有特殊需求否则不推荐。驱动文件你需要从Oracle官网或Maven中央仓库获取ojdbc的JAR文件。请彻底忘记ojdbc14.jar这个命名对应的是JDK 1.4早已过时。现代的驱动版本号与Oracle数据库版本和JDK版本相关。版本选择Oracle 11g推荐使用ojdbc6.jar(对应JDK 6/7/8) 或ojdbc8.jar。Oracle 12c, 18c, 19c, 21c强烈推荐使用ojdbc8.jar。它对JDK 8及以上版本支持最好也兼容更新的数据库特性。Oracle 23c及以上使用ojdbc11.jar或更高版本。如何获取最推荐的方式是通过Maven/Gradle等构建工具管理依赖省去手动下载和添加Classpath的麻烦。Maven依赖配置示例!-- 连接Oracle 19c使用最新的稳定版驱动 -- dependency groupIdcom.oracle.database.jdbc/groupId artifactIdojdbc8/artifactId version21.9.0.0/version !-- 注意版本号建议查最新 -- scoperuntime/scope /dependency实操心得驱动版本不匹配导致的错误五花八门比如ClassNotFoundException: oracle.jdbc.OracleDriver或者不兼容的SQLException。一个简单的原则你的ojdbc驱动的主版本号应该大于等于你的JDK主版本号如JDK 11用ojdbc11并且最好从官方渠道获取对应数据库版本的认证驱动。2.3 构建项目与IDE配置创建一个普通的Java项目即可。如果你使用IDE如IntelliJ IDEA或Eclipse确保项目使用的JDK版本与你选择的驱动兼容如用ojdbc8JDK至少是8。驱动JAR文件已被正确添加到项目的构建路径Build Path或模块依赖Module Dependencies中。如果使用Maven刷新依赖即可。3. 基础连接从DriverManager到Connection万事俱备现在我们来写第一段能跑通的连接代码。我们将使用最经典的java.sql.DriverManager方式。3.1 核心四要素与连接字符串建立连接需要四个核心信息拼装成一个JDBC URL连接字符串主机名/IP地址数据库服务器地址。端口号监听端口默认1521。服务名/SID这是最容易混淆的点。Oracle有两种标识数据库的方式SID较老和Service Name推荐。你需要向DBA确认或用select name from v$database;SID和select value from v$parameter where nameservice_names;服务名查询。用户名/密码登录凭证。连接字符串格式使用服务名Service Namejdbc:oracle:thin://host:port/service_name示例jdbc:oracle:thin://192.168.1.100:1521/ORCLPDB1使用SID较旧格式jdbc:oracle:thin:host:port:sid示例jdbc:oracle:thin:192.168.1.100:1521:ORCL为什么推荐服务名在Oracle多租户架构12c以后中可插拔数据库PDB使用服务名访问更为标准和灵活。SID方式可能无法直接连接到PDB。3.2 编写第一个连接示例下面是一个完整的、包含基础异常处理的连接示例import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class OracleJdbcExample { // 定义连接参数 private static final String URL jdbc:oracle:thin://localhost:1521/ORCLPDB1; private static final String USER your_username; private static final String PASSWORD your_password; public static void main(String[] args) { Connection connection null; try { // 1. 显式加载驱动类对于新版本驱动这步不是必须的但显式声明是好习惯 Class.forName(oracle.jdbc.OracleDriver); // 2. 通过DriverManager获取连接 connection DriverManager.getConnection(URL, USER, PASSWORD); // 3. 连接成功后的操作 if (connection ! null !connection.isClosed()) { System.out.println(恭喜成功连接到Oracle数据库。); // 这里可以执行查询等操作后续章节展开 } } catch (ClassNotFoundException e) { System.err.println(找不到JDBC驱动类请检查ojdbc jar包是否在类路径中。); e.printStackTrace(); } catch (SQLException e) { System.err.println(数据库连接失败请检查URL、用户名、密码及网络。); System.err.println(错误信息: e.getMessage()); System.err.println(错误代码: e.getErrorCode()); e.printStackTrace(); } finally { // 4. 在finally块中确保连接被关闭 if (connection ! null) { try { connection.close(); System.out.println(数据库连接已关闭。); } catch (SQLException e) { e.printStackTrace(); } } } } }代码逐行解析Class.forName(...)在早期JDBC规范中这行代码是必须的用于动态加载驱动类。从JDBC 4.0随JDK 6引入开始驱动可以通过META-INF/services/java.sql.Driver文件自动注册所以这行代码变得可选。但显式写出是一个清晰且兼容性好的做法。DriverManager.getConnection()核心方法传入URL、用户、密码三个参数返回一个Connection对象。这个对象是所有后续数据库操作创建语句、执行查询、事务管理的起点。connection.isClosed()判断连接是否已关闭。异常处理ClassNotFoundException通常意味着驱动JAR没放对地方。SQLException是数据库操作的主要异常其getMessage()和getErrorCode()方法能提供非常具体的错误信息是排查问题的第一手资料。资源关闭Connection是宝贵的资源必须在使用后关闭。放在finally块中确保即使发生异常也能执行关闭操作。这是防止连接泄漏Connection Leak的基本功。3.3 连接参数与属性扩展除了基本的URL、用户、密码你还可以通过Properties对象或直接在URL后追加参数来传递更多连接属性。使用Properties对象import java.util.Properties; Properties props new Properties(); props.put(user, USER); props.put(password, PASSWORD); // 设置连接属性 props.put(oracle.jdbc.ReadTimeout, 5000); // 设置socket读取超时5秒 props.put(remarksReporting, true); // 允许获取表注释等信息 connection DriverManager.getConnection(URL, props);在URL中追加参数String urlWithParams URL ?oracle.net.CONNECT_TIMEOUT3000oracle.jdbc.ReadTimeout5000; connection DriverManager.getConnection(urlWithParams, USER, PASSWORD);常用连接属性oracle.net.CONNECT_TIMEOUT建立TCP连接的超时时间毫秒。oracle.jdbc.ReadTimeoutsocket读取超时时间毫秒对于慢查询或网络不稳很有用。remarksReporting设置为true后DatabaseMetaData.getTables()等方法才能返回表的备注信息。实操心得生产环境中务必设置合理的超时参数。默认情况下网络故障可能导致应用线程无限期挂起。将连接超时和读取超时设置为5-30秒是一个常见的做法超时后抛出异常便于应用做重试或降级处理而不是永远等待。4. 执行SQL与处理结果集拿到Connection之后我们终于可以跟数据库“对话”了。核心接口是Statement、PreparedStatement和ResultSet。4.1 使用Statement执行查询Statement用于执行静态SQL语句即没有参数的SQL。Statement stmt null; ResultSet rs null; try { stmt connection.createStatement(); // 执行查询返回ResultSet rs stmt.executeQuery(SELECT employee_id, first_name, last_name FROM employees WHERE department_id 50); // 遍历结果集 while (rs.next()) { // rs.next()移动游标并判断是否有下一行数据 int id rs.getInt(employee_id); // 通过列名获取推荐 // int id rs.getInt(1); // 通过列索引获取从1开始 String firstName rs.getString(first_name); String lastName rs.getString(last_name); System.out.printf(ID: %d, Name: %s %s%n, id, firstName, lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭结果集和语句 try { if (rs ! null) rs.close(); } catch (SQLException e) { e.printStackTrace(); } try { if (stmt ! null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); } }关键点executeQuery(String sql)用于执行SELECT语句返回ResultSet。rs.next()这是操作结果集的核心。它做两件事将游标移动到下一行返回一个布尔值指示新行是否有效。必须在读取数据前调用。getXxx()方法根据列的数据类型选择对应的方法如getInt,getString,getDate,getBigDecimal等。使用列名比列索引更清晰、更安全即使SQL中列顺序改变代码也不受影响。资源关闭顺序遵循后开先关原则先关ResultSet再关Statement最后关Connection。4.2 使用PreparedStatement防止SQL注入与提升性能Statement直接拼接SQL字符串非常危险容易导致SQL注入攻击。例如如果用户输入department_id的值是50 OR 11那么整个WHERE条件就失效了可能泄露全表数据。绝对不要这样做String userInput 50 OR 11; String sql SELECT * FROM employees WHERE department_id userInput; // 危险 Statement stmt connection.createStatement(); stmt.executeQuery(sql);正确的做法是使用PreparedStatement。它使用占位符?来预编译SQL然后将参数安全地传递进去。String sql SELECT employee_id, first_name FROM employees WHERE department_id ? AND salary ?; PreparedStatement pstmt null; ResultSet rs null; try { pstmt connection.prepareStatement(sql); // 预编译SQL // 设置参数索引从1开始 pstmt.setInt(1, 50); // 设置第一个?为整数50 pstmt.setBigDecimal(2, new BigDecimal(5000.00)); // 设置第二个?为BigDecimal rs pstmt.executeQuery(); // 注意这里不需要再传入SQL字符串 while (rs.next()) { // ... 处理结果 } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源... }为什么PreparedStatement更好安全性从根本上杜绝SQL注入。参数值会被驱动程序正确地转义和处理不会被解释为SQL的一部分。性能SQL语句被数据库预编译和缓存。当需要多次执行同一条SQL仅参数不同时数据库无需重复解析和优化SQL性能显著提升。可读性与维护性SQL和参数分离代码更清晰。实操心得在任何可能接受用户输入或外部参数的地方必须使用PreparedStatement这是铁律。即使是内部系统、固定参数养成使用PreparedStatement的习惯也是极好的。4.3 执行更新与获取自增键对于INSERT、UPDATE、DELETE操作我们使用executeUpdate()方法。String insertSql INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id) VALUES (?, ?, ?, ?, SYSDATE, ?); PreparedStatement pstmt connection.prepareStatement(insertSql); pstmt.setInt(1, 1000); pstmt.setString(2, 张); pstmt.setString(3, 三); pstmt.setString(4, zhangsanexample.com); pstmt.setString(5, IT_PROG); int affectedRows pstmt.executeUpdate(); System.out.println(插入了 affectedRows 行数据。); pstmt.close();获取自动生成的主键在Oracle中主键通常通过序列Sequence和触发器Trigger生成。执行插入后可以通过指定一个标志来获取生成的主键。// 创建PreparedStatement时告知需要返回生成的键 String[] generatedColumns {EMPLOYEE_ID}; // 主键列名 PreparedStatement pstmt connection.prepareStatement(insertSql, generatedColumns); // ... 设置其他参数注意EMPLOYEE_ID对应的参数不设值或设为序列的nextval // 假设表上有触发器自动从序列赋值这里就不设置第一个参数 // pstmt.setInt(1, ...); // 注释掉或使用 DEFAULT pstmt.executeUpdate(); ResultSet generatedKeys pstmt.getGeneratedKeys(); if (generatedKeys.next()) { long newId generatedKeys.getLong(1); System.out.println(新生成的员工ID是: newId); } generatedKeys.close(); pstmt.close();5. 事务管理与连接池实战单个操作没问题了但真实业务往往是多个操作组成一个逻辑单元这就需要事务。而频繁创建关闭连接开销巨大这就需要连接池。5.1 手动事务控制JDBC中默认是自动提交模式auto-committrue即每条SQL都是一个独立的事务。要手动控制事务需要关闭自动提交。Connection conn null; PreparedStatement pstmt1 null; PreparedStatement pstmt2 null; try { conn DriverManager.getConnection(URL, USER, PASSWORD); conn.setAutoCommit(false); // 1. 关闭自动提交开启事务 // 执行第一个更新 pstmt1 conn.prepareStatement(UPDATE accounts SET balance balance - ? WHERE account_id ?); pstmt1.setBigDecimal(1, new BigDecimal(100.00)); pstmt1.setInt(2, 101); pstmt1.executeUpdate(); // 执行第二个更新 pstmt2 conn.prepareStatement(UPDATE accounts SET balance balance ? WHERE account_id ?); pstmt2.setBigDecimal(1, new BigDecimal(100.00)); pstmt2.setInt(2, 102); pstmt2.executeUpdate(); // 所有操作成功提交事务 conn.commit(); System.out.println(转账成功); } catch (SQLException e) { // 发生异常回滚事务 if (conn ! null) { try { conn.rollback(); System.out.println(发生错误事务已回滚。); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { // 恢复自动提交可选并关闭资源 try { if (conn ! null) conn.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); } // 关闭Statement和Connection... }事务要点setAutoCommit(false)标志事务开始。commit()提交事务所有更改永久生效。rollback()回滚事务撤销所有未提交的更改。一定要在finally块或try-with-resources中确保连接被正确关闭关闭连接前如果事务未提交或回滚某些驱动可能会自动回滚但显式控制更安全。5.2 引入数据库连接池HikariCP为例直接使用DriverManager每次操作都创建物理连接耗时耗资源。连接池预先创建一批连接应用需要时从池中取用用完后归还避免了频繁创建和销毁的开销。这里以目前性能顶尖的HikariCP为例。1. 添加Maven依赖dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version5.0.1/version /dependency dependency groupIdcom.oracle.database.jdbc/groupId artifactIdojdbc8/artifactId version21.9.0.0/version /dependency2. 配置并使用HikariCPimport com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.SQLException; public class HikariCPExample { private static HikariDataSource dataSource; static { // 配置连接池 HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:oracle:thin://localhost:1521/ORCLPDB1); config.setUsername(your_username); config.setPassword(your_password); config.setDriverClassName(oracle.jdbc.OracleDriver); // 连接池参数根据实际调整 config.setMaximumPoolSize(10); // 最大连接数 config.setMinimumIdle(5); // 最小空闲连接数 config.setConnectionTimeout(30000); // 获取连接超时时间毫秒 config.setIdleTimeout(600000); // 连接空闲超时时间毫秒 config.setMaxLifetime(1800000); // 连接最大生命周期毫秒 config.setConnectionTestQuery(SELECT 1 FROM DUAL); // Oracle的测试查询 dataSource new HikariDataSource(config); } public static Connection getConnection() throws SQLException { // 从池中获取连接 return dataSource.getConnection(); } public static void main(String[] args) { try (Connection conn getConnection()) { // try-with-resources自动关闭 System.out.println(从HikariCP连接池获取连接成功); // ... 使用conn执行数据库操作 } catch (SQLException e) { e.printStackTrace(); } // 应用关闭时关闭数据源通常放在ServletContextListener中 // if (dataSource ! null) dataSource.close(); } }HikariCP关键参数解析maximumPoolSize池中最大连接数。不是越大越好需根据数据库和应用负载调整。一般公式pool size Tn * (Cm - 1) 1其中Tn是线程数Cm是每个线程同时需要的连接数。对于大多数Web应用10-20是个不错的起点。minimumIdle池中保持的最小空闲连接数。HikariCP建议不设置或等于maximumPoolSize让它动态管理性能更好。connectionTimeout从池中获取连接的超时时间。如果所有连接都在忙超过此时间将抛出SQLTimeoutException。必须设置防止线程无限等待。idleTimeout/maxLifetime连接空闲和最大存活时间用于淘汰老旧或空闲连接防止网络或数据库端连接失效。Oracle会话可能有超时限制设置略小于数据库超时时间是个好主意。实操心得连接池是生产级应用的标配。HikariCP以其简单和高效成为首选。配置时connectionTimeout和maxLifetime尤为重要。获取连接超时能快速失败避免雪崩。连接最大生命周期能定期刷新连接避免数据库端因长时间空闲而断开的“死连接”被分配给应用导致报错。6. 常见问题排查与性能优化锦囊即使按照步骤操作你可能还是会遇到问题。这里汇总一些典型场景和排查思路。6.1 连接失败类问题错误现象/信息可能原因排查步骤ClassNotFoundException: oracle.jdbc.OracleDriver驱动JAR未在类路径中。1. 检查ojdbcJAR是否被正确添加到项目依赖或lib目录。2. 检查Maven/Gradle依赖是否下载成功。3. 对于Web项目检查JAR是否在WEB-INF/lib下。ORA-12541: TNS: 无监听程序数据库监听器未启动或IP/端口错误。1. 在数据库服务器执行lsnrctl status。2. 检查连接URL中的主机名和端口默认1521。3. 确认客户端网络能通telnet host 1521。ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务连接字符串中的服务名Service Name错误。1. 登录数据库执行select value from v$parameter where nameservice_names;获取正确服务名。2. 检查URL格式使用服务名应为//host:port/service_name。ORA-01017: invalid username/password; logon denied用户名或密码错误或用户无连接权限。1. 仔细核对用户名、密码大小写。2. 用SQL*Plus等工具使用相同凭证测试。3. 确认用户是否被锁定或过期。IO Error: The Network Adapter could not establish the connection网络问题或防火墙阻止。1. 检查数据库服务器防火墙是否开放了1521端口。2. 检查客户端到服务器的网络路由。6.2 执行SQL类问题错误现象/信息可能原因排查步骤ORA-00942: table or view does not exist表名或视图名错误或当前用户无权限访问。1. 检查表名拼写和大小写Oracle默认大写。2. 确认连接的用户是否有SELECT等权限。3. 确认表是否在正确的模式Schema下可能需要加上模式名前缀如SCOTT.EMPLOYEES。ORA-01722: invalid number字符串无法转换为数字。1. 检查PreparedStatement中setInt、setBigDecimal等方法的参数类型是否与数据库列类型匹配。2. 检查传入的字符串是否包含非数字字符。查询结果集为空但数据库有数据SQL条件错误或字符集问题导致比较失败。1. 将Java中拼接的SQL打印出来直接在数据库客户端执行验证结果。2. 注意字符串末尾空格使用TRIM()函数或确保参数无误。3. 检查NLS字符集设置确保应用和数据库字符集一致如AL32UTF8。6.3 性能与资源类问题连接泄漏现象是应用运行一段时间后无法获取新连接池子耗尽。根本原因是代码中获取了Connection、Statement或ResultSet后没有在finally块或使用try-with-resources语法确保关闭。解决方案强制使用try-with-resources语法Java 7它是防止资源泄漏的最佳实践。// 推荐写法自动关闭无需finally try (Connection conn dataSource.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql); ResultSet rs pstmt.executeQuery()) { while (rs.next()) { // 处理数据 } } catch (SQLException e) { e.printStackTrace(); }慢查询个别SQL执行缓慢拖累整体。排查在数据库端开启监控或使用AWR/ASH报告找到高消耗的SQL。在Java端可以配置JDBC驱动日志或使用第三方工具如p6spy拦截并打印真实SQL及其执行时间。优化为查询条件字段添加索引避免SELECT *只取需要的列分析执行计划。连接池配置不当maximumPoolSize过大导致数据库连接数过多耗尽数据库资源过小则应用并发能力差。调优通过监控连接池的活跃连接数、空闲连接数、等待线程数等指标HikariCP提供JMX监控动态调整池大小。初始值可设为CPU核心数的2-3倍。最后的小技巧在开发环境可以在JDBC URL中加入参数oracle.jdbc.Tracetrue并在驱动日志配置中启用这能打印出详细的JDBC调用和网络通信信息对调试复杂问题非常有帮助但生产环境务必关闭。从驱动选择、URL拼写、PreparedStatement防注入到事务控制、连接池配置再到问题排查Java连接Oracle的每一个环节都需要细心对待。把这些基础打牢不仅是完成一个连接任务更是构建稳定、高效数据访问层的开始。当你再遇到ORA-xxxxx的错误时希望你能从容地根据错误代码和信息快速定位到问题所在。

相关新闻

从设计语言到工程实现:深度解析新一代K3运动化设计的底层逻辑

从设计语言到工程实现:深度解析新一代K3运动化设计的底层逻辑

2026/8/18 3:16:37

1. 从官图到实车:如何解读一款新车的设计语言?最近,起亚官方发布了国产新一代K3的外观官图,核心信息点很明确:“造型更运动”。对于汽车爱好者、潜在购车者,甚至是行业内的设计师和产品经理来说&#xff0c…

AI Agent+RPA技术实现课程自动化:架构、原理与教育防御策略

AI Agent+RPA技术实现课程自动化:架构、原理与教育防御策略

2026/8/18 3:16:37

当一门在线课程要求学生完成讨论、作业、考试,而学生只需输入课程链接和账号密码,剩下的所有环节都由一个“数字替身”自动完成时,教育意味着什么?这并非科幻场景,而是正在部分美国高校真实上演的“AI逃课”现象。学生…

Agent 37:低成本OpenClaw AI实例部署与应用指南

Agent 37:低成本OpenClaw AI实例部署与应用指南

2026/8/18 3:16:37

1. Agent 37服务概述:低成本专属AI实例解决方案 今天在ProductHunt热榜上发现一个有意思的服务——Agent 37,每月只需3.99美元就能获得专属的OpenClaw实例。这个价格对于个人开发者和小团队来说相当友好,相当于一杯咖啡的钱就能拥有一个持续运…

嵌入式驱动设计:阻塞与非阻塞模式的核心原理与实战选型指南

嵌入式驱动设计:阻塞与非阻塞模式的核心原理与实战选型指南

2026/8/18 4:06:39

1. 项目概述:阻塞与非阻塞驱动,嵌入式开发的十字路口在嵌入式系统开发里,驱动是连接硬件和应用软件的桥梁,它的行为模式直接决定了整个系统的响应能力和效率。今天我们不谈高深的理论,就聊聊每个嵌入式工程师在写驱动时…

自动化浏览器操作:Playwright / Selenium MCP 让Agent像人一样点击、填表、抓取动态网页

自动化浏览器操作:Playwright / Selenium MCP 让Agent像人一样点击、填表、抓取动态网页

2026/8/18 4:06:39

在过去的几年里,大语言模型(LLM)和AI Agent的概念席卷了整个技术圈。我们习惯了让ChatGPT写诗、写代码、做总结,但有一个问题始终悬而未决:AI能不能像人一样,真正“操作”这个世界? 答案正在变得清晰——能。而连接AI与数字世界的桥梁,就是自动化浏览器操作。 试想这…

日历与日程管理:操作Google Calendar API实现会议安排、日程冲突检测

日历与日程管理:操作Google Calendar API实现会议安排、日程冲突检测

2026/8/18 4:06:39

引言 在当今快节奏的工作环境中,高效的时间管理已成为个人和团队成功的关键因素之一。日历与日程管理工具不再仅仅是记录事件的简单工具,而是演变成了智能化的时间调度中心。Google Calendar作为全球最广泛使用的日历服务之一,其强大的API接口为开发者提供了丰富的功能扩展…

WinForms声明式配置工具ZL.ParamEditor实战指南

WinForms声明式配置工具ZL.ParamEditor实战指南

2026/8/18 4:06:39

1. WinForms配置的痛点与革新 十五年前我刚接触WinForms开发时,配置一个带数据绑定的表单需要反复修改.cs和.Designer文件,每次调整控件属性都要在代码堆里翻找。直到发现声明式配置工具ZL.ParamEditor,才真正体会到什么叫"开发体验升级…

Llamafactory微调与Ollama部署:打造专属大模型的完整实践指南

Llamafactory微调与Ollama部署:打造专属大模型的完整实践指南

2026/8/18 4:06:39

1. 先搞清楚这套组合拳到底能解决什么问题如果你在Linux环境下,想基于自己的数据对大模型做微调,并且希望最终能有一个像Ollama那样简单易用的本地部署和交互方式,那么“Llamafactory微调 Ollama格式打包”这条技术路线,就值得你…

Spring Boot 2.7.x整合springfox-swagger 3.0.0:平滑升级OpenAPI 3.0实践

Spring Boot 2.7.x整合springfox-swagger 3.0.0:平滑升级OpenAPI 3.0实践

2026/8/18 3:56:38

1. 项目缘起:为什么在Spring Boot 3.x时代,我们还需要关注springfox-swagger 3.0.0?如果你是一位Spring Boot的开发者,尤其是经历过从2.x到3.x版本升级的,那么对于API文档工具的选择,你可能会感到一丝困惑。…

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

2026/8/17 1:28:42

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

【双层规划,节点出清价,绿证交易,CVaR方法】两级电力市场环境下计及风险的省间交易商最优购电模型附Matlab代码

2026/8/18 1:03:22

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

隐式mpc+自适应mpc+时变mpc,线性时变模型预测控制附Simulink仿真

2026/8/17 8:40:51

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

多智能体大模型辩论中的立场收敛:从伪共识到理性说服的评估方法

多智能体大模型辩论中的立场收敛:从伪共识到理性说服的评估方法

2026/8/18 0:06:29

1. 从一场“假辩论”说起:为什么大模型辩论会走向“伪共识”?最近在折腾多智能体大语言模型(Multi-Agent LLM)的辩论实验,发现一个挺有意思的现象。我让几个基于GPT-4的智能体就一个争议性话题(比如“远程办…

Frida动态代码插桩框架:从原理到实战的移动安全与逆向工程指南

Frida动态代码插桩框架:从原理到实战的移动安全与逆向工程指南

2026/8/18 0:06:29

1. 从“黑盒”到“白盒”:为什么我们需要Frida在移动安全、逆向工程甚至是一些自动化测试的场景里,我们经常会遇到一个让人头疼的问题:面对一个编译好的、没有源代码的应用程序,我们如何知道它在运行时内部发生了什么?…

ECharts饼图中心文字配置指南:从label与title区别到动态交互实现

ECharts饼图中心文字配置指南:从label与title区别到动态交互实现

2026/8/18 0:06:29

1. 从“空心”到“有魂”:为什么要在饼图中间加文字?如果你用过ECharts画饼图,大概率会注意到一个现象:默认生成的饼图中间是空心的。这个设计本身没问题,它清晰地展示了各个扇区的占比关系。但在很多实际的业务场景里…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/17 12:00:53

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/14 19:35:14

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…