|
Java连数据库,连接本质上就干三件事:加载驱动、数据建立连接、连接执行SQL。数据别被各种框架绕晕,连接JDBC才是数据根。 我见过太多新手一上来就整MyBatis、连接Spring Data JPA,数据结果报错连个堆栈都看不懂。连接老老实实从JDBC起步,数据比什么都强。连接拿MySQL举例,数据驱动就一行代码:Class.forName("com.mysql.cj.jdbc.Driver")。连接这行代码的数据作用是让JVM认识MySQL的协议,不认识它,连接后面全白搭。 连接字符串长这样:jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC。端口3306是MySQL默认的,test是你库名。时区那个参数不写,新版驱动直接报错,别问为什么,问就是UTC标准。用DriverManager.getConnection(url, "root", "password")拿到Connection对象——记住,这个对象代表一次物理连接,用完必须关。 真正写代码时,坑不在连接,在Statement。我见过有人把参数直接拼SQL字符串,结果被注入得裤子都不剩。一定要用PreparedStatement,占位符问号那种。比如: String sql = "SELECT * FROM users WHERE id = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setInt(1, 100); ResultSet rs = ps.executeQuery(); 注意看,这里没有拼接,只有绑定。setInt把参数安全地传给数据库,既防注入,又不用手动处理引号转义。执行查询用executeQuery(),返回ResultSet——一个类似游标的东西。遍历它用while(rs.next()),像翻书页一样一行行取数据。rs.getInt("id")、rs.getString("name"),按列名取,比按下标取可读性好得多。 插入、更新、删除这类操作,用ps.executeUpdate(),返回受影响的行数。比如删掉一条记录,返回1就说明删成功了。别觉得这简单,实际项目里很多人连返回值都不检查,数据没删掉都不知道。 事务处理是另一个高频翻车点。默认情况下,Connection是自动提交的——每条SQL执行完立刻落库。但业务场景往往是“先扣库存,再生成订单”,两步必须同时成功或同时失败。这时候你要关掉自动提交:conn.setAutoCommit(false),然后执行你的多条SQL,都成功了再conn.commit(),任何一步抛异常就conn.rollback()。别忘了finally里把资源关掉,顺序是ResultSet → Statement → Connection,反着关。 最后说个实际观察:很多人觉得连接池是后期优化才用的东西。错。哪怕你写个命令行小工具,也建议用HikariCP(一个轻量连接池)。为什么?因为每次new Connection都要经过TCP握手、MySQL认证,开销几十毫秒起步。连接池提前建好一堆连接复用,性能差距在循环操作时能达到数量级。配置就几行: HikariConfig config = new HikariConfig(); config.setJdbcUrl(url); config.setUsername("root"); config.setPassword("password"); HikariDataSource ds = new HikariDataSource(config); 之后从ds.getConnection()拿连接,用完了调用close()——注意,这个close不是真关,是还回池子里。刚开始可能不习惯,但用顺手了你会觉得这设计挺聪明。 说到底,连接数据库这活儿,核心就是管理好两个东西:连接的生命周期,以及SQL的执行状态。前者靠连接池和try-with-resources(Java 7+的语法糖,自动关资源),后者靠PreparedStatement和事务边界。把这两点拿捏住,什么框架都是锦上添花。你要是真把JDBC底层摸透了,再去看MyBatis的源码,会发现它不过是在帮你拼SQL和映射结果集罢了。 |