JDBC资源包
链接:https://pan.baidu.com/s/1JaZ3...
提取码:858d
JDBC操作数据库流程
- Class.forName()加载数据库连接驱动。
- DriverManager.getConnection()获取数据连接对象。
- 根据SQL语句获取会话对象,会话对象一般用PreparedStatement类型
- 执行SQL处理结果集
- 关闭结果集、关闭会话、关闭连接
封装函数
public class SqlUtils { private static String driver = "com.mysql.jdbc.Driver"; private static String url = ""; private static String username = ""; private static String password = ""; static { //加载驱动 try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } //只产生一个连接 public static Connection getConnection() throws SQLException { System.out.println("连接数据库..."); return DriverManager.getConnection(url, username, password); } public static void release(Connection connection, Statement statement, ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }}
测试用例
public class test { public static void main(String[] args) throws SQLException { //加载驱动,创建连接 Connection connection = SqlUtils.getConnection(); //SQL语句 String insert = "INSERT INTO `user` (id,username,password) VALUE (?,?,?);"; String select = "SELECT * FROM `user`;"; //将事务设置为手动提交 connection.setAutoCommit(false); PreparedStatement statement1; PreparedStatement statement2; try{ //根据sql语句,得到预编译语句对象 statement1 = connection.prepareStatement(insert); statement2 = connection.prepareStatement(select); for(int i=1;i<=10;i++){ //按占位符设置参数值 statement1.setInt(1,i); statement1.setString(2,"user_"+i); statement1.setString(3,"password"+i); //放入批处理队列 statement1.addBatch(); } //执行插入语句,批量插入,事务 statement1.executeBatch(); //执行查询语句,得到结果集 ResultSet result = statement2.executeQuery(); //遍历、打印结果 while (result.next()){ System.out.println("username:"+result.getObject("username")+";password:"+result.getObject("password")); } //提交事务 connection.commit(); //关闭连接,释放资源 SqlUtils.release(connection,statement1,result); SqlUtils.release(connection,statement2,result); }catch (Exception e){ e.printStackTrace(); } }}
Statement对象和PreparedStatement对象
PreparedStatement继承Statement,PreparedStatement包含已编译的SQL语句,其执行速度比Statement要快。Statement会频繁编译SQL。PreparedStatement可对SQL进行预编译,提高效率,预编译的SQL存储在PreparedStatement对象中。
在JDBC中,任何时候都不要用Statement,因为:
- 代码的可读性和维护性,Statement需要不断的拼接
- PreparedStatement性能更好,有缓存机制
- PreparedStatement安全性更加高,Statement容易被sql注入,通过分隔符'++',编写永等式,可以不需要密码就进入数据库,PreparedStatement传入的内容不会和sql语句发生任何匹配关系
数据库连接池的机制
准备:建立一个数据库缓冲池
- 从连接池获取或创建连接
- 使用结束,连接返回连接池
- 在系统关闭时,断开所有连接并释放资源
- 能够处理无效连接,限制连接池的总数不低于而不高于某个值
最小连接数:连接池一直保持的连接数
最大连接数:连接池可以申请最大的连接数,如果超过,后面的数据连接请求进入等待队列
连接池一直保持着不少于最小连接数的数量,当数量不够时,数据库会创建新的连接,直到达到最大的连接数,之后数据库会一直等待
常见开源的连接池:DBCP、C3P0、Druid