1. JDBC 基本概念
  2. 快速入门
  3. 对JDBC中各个接口和类详解

JDBC

  1. 概念:Java DataBase Connectivity Java 数据库连接,java语言操作数据库
    • JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
  2. 快速入门:
    • 步骤:
      1. 导入驱动jar包
      2. 注册驱动
      3. 获取数据库连接对象 Connection
      4. 定义sql
      5. 获取执行sql语句的对象 Statement
      6. 执行sql,接受返回结果
      7. 处理结果
      8. 释放资源
    • 代码演示:```java package a_jdbc;

import java.sql.*;

public class JDBCDemo1 {

  1. public static void main(String[] args) throws ClassNotFoundException, SQLException {
  2. //1,导入驱动jar包
  3. //2,注册驱动
  4. Class.forName("com.mysql.jdbc.Driver");
  5. //3,获取数据库连接对象

// Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/db0”, “root”, “1314525xj”); Connection conn = DriverManager.getConnection(“jdbc:mysql:///db0”, “root”, “1314525xj”); //4,定义sql语句 String sql = “update stu set name = ‘徐无敌’ where name = ‘徐杰’”; //5,获取执行sql的对象 Statement stmt = conn.createStatement(); //6,执行sql int count = stmt.executeUpdate(sql); //7,处理结果 System.out.println(count); //8,释放资源 stmt.close(); conn.close(); } }

  1. <br />
  2. 3. 详解各个对象
  3. 1. `DriverManager`:驱动管理对象
  4. - 功能:
  5. 1. 注册驱动<br />`static void registerDriver(Driver driver)`:注册给定的驱动程序`DriverManager`

写代码使用:Class.forName("com.mysql.jdbc.Driver");

  1. <br /> 通过查看源码发现:在`com.mysql.jdbc.Driver`中存在静态代码块```java
  2. static {
  3. try {
  4. DriverManager.registerDriver(new Driver());
  5. } catch (SQLException var1) {
  6. throw new RuntimeException("Can't register driver!");
  7. }
  8. }


注意:mysql5之后的驱动jar包可以省略

  1. 2. 获取数据库连接
  2. - 方法:`static Connection getConnection(String url, String user, String password)`
  3. - 参数:
  4. - url:指定连接的路径
  5. - 语法:`jdbc:mysql://ip地址(域名):端口号/数据库名称`
  6. - 例子: `jdbc:mysql://localhost:3306/db0`
  7. - 细节: 如果连接是本机的mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///db0
  1. Connection:数据库连接对象
    1. 功能:
      1. 获取执行sql的对象
        • Statement createStatement()
        • PreparedStatement prepareStatement(String sql)
      2. 管理事务:
        • 开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
        • 提交事务:commit()
        • 回滚事务: rollback()
  2. Statement:执行sql的对象
    1. 执行sql
      1. boolean execute(String sql):可以执行任意的sql
      2. int executeUpdate(String sql):可以执行DML(insert,update,delete)语句,DDL(create,alter,drop)语句
        • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功。>0成功,反之失败
      3. ResultSet executeQuery(String sql):执行DQL(select)语句
  3. ResultSet:结果集对象,封装查询结果

    • boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,若不是,则返回true
    • getXxx(): 获取数据
      • Xxx: 代表数据类型 如:int getInt() String getString()
      • 参数:
        1. int : 代表列的编号,从1开始 如:getString(1)
        2. String :代表列的名称。 如:getString(“name”)
    • 注意:
      • 使用步骤:
        1. 游标向下移动一行
        2. 判断是否有数据
        3. 获取数据
          1. //循环判断游标是否是最后一行
          2. while(rs.next()){
          3. int id = rs.getInt(1);
          4. System.out.println(id);
          5. }
  4. PerparedStatement:执行sql的对象

    1. SQL注入问题:在拼接sql时,有一些sql的特殊性关键字参与字符串的拼接,会造成安全性问题。
      1. 输入用户随便,输入密码:a' or 'a' = 'a
      2. sql:select * from user = 'awfs' and password = 'sdfsd' or 'a' = 'a';
    2. 解决sql注入问题:使用Preparestatement对象解决
    3. 预编译的SQL:参数使用?作为占位符
    4. 步骤

      1. 导入驱动jar包
      2. 注册驱动
      3. 获取数据库连接对象 Connection
      4. 定义sql
        • 注意:sql的参数使用?作为占位符。如:select * from user where username = ? and password = ?;
      5. 获取执行sql语句的对象 PreparedStatement Connection.preparedStatement(String sql)
      6. 给?赋值:
        • 方法:setXxx(参数1,参数2)
          • 参数1:?的位置 编号从1开始
          • 参数2:?的值
      7. 执行sql,接受返回结果,不需要传递sql了
      8. 处理结果
      9. 释放资源 ```java public boolean login2(String username,String password){ Connection connection = null; Statement statement = null; ResultSet resultSet = null; PreparedStatement preparedStatement = null; if (username == null || password == null){ return false; }

      //1获取连接 try { connection = JDBCUtils.getConnection(); String sql = “Select * from user where username = ? and password = ?”; preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1,username); preparedStatement.setString(2,password); resultSet = preparedStatement.executeQuery(); System.out.println(sql); return resultSet.next(); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.close(resultSet,preparedStatement,connection); }

      return false; } ```

    5. 注意:后期都会使用Preparestatement来完成增删改查的所有操作

      1. 可以防止SQL注入
      2. 效率更高

抽取JDBC工具类:JDBCUtils

  • 目的:简化书写
  • 分析:
    1. 注册驱动也抽取
    2. 抽取一个方法获取连接对象
      • 需求:不传参,还得保证工具类的通用性
      • 解决:配置文件
    3. 抽取释放资源的方法
  1. package a_jdbc;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.net.URL;
  5. import java.sql.*;
  6. import java.util.Properties;
  7. @SuppressWarnings("All")
  8. public class JDBCUtils {
  9. private static String url;
  10. private static String user;
  11. private static String password;
  12. private static String driver;
  13. /**
  14. * 文件的读取,只需要读取一次即可拿到这些,静态代码块
  15. */
  16. static {
  17. try {
  18. //1.创建Properties集合类
  19. Properties pro = new Properties();
  20. //获取src路径下的文件的方式-->ClassLoader
  21. ClassLoader classLoader = JDBCUtils.class.getClassLoader();
  22. URL res = classLoader.getResource("jdbc.properties");
  23. String path = res.getPath();
  24. System.out.println(path);
  25. //2.加载文件
  26. pro.load(new FileReader("src/javaWeb/jdbc.properties"));
  27. //3.获取数据
  28. url = pro.getProperty("url");
  29. user = pro.getProperty("user");
  30. password = pro.getProperty("password");
  31. driver = pro.getProperty("driver");
  32. //4.注册驱动
  33. Class.forName(driver);
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. } catch (ClassNotFoundException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. /**
  41. * 获取连接
  42. *
  43. * @return 连接对象
  44. */
  45. public static Connection getConnection() throws SQLException {
  46. return DriverManager.getConnection(url,user,password);
  47. }
  48. /**
  49. * 释放资源
  50. * @param stmt
  51. * @param conn
  52. */
  53. public static void close(Statement stmt, Connection conn) {
  54. try {
  55. if (stmt != null) {
  56. stmt.close();
  57. }
  58. } catch (SQLException e) {
  59. e.printStackTrace();
  60. }
  61. try {
  62. if (conn != null) {
  63. conn.close();
  64. }
  65. } catch (SQLException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. public static void close(ResultSet rs,Statement stmt, Connection conn) {
  70. try {
  71. if (rs != null) {
  72. rs.close();
  73. }
  74. } catch (SQLException e) {
  75. e.printStackTrace();
  76. }
  77. try {
  78. if (stmt != null) {
  79. stmt.close();
  80. }
  81. } catch (SQLException e) {
  82. e.printStackTrace();
  83. }
  84. try {
  85. if (conn != null) {
  86. conn.close();
  87. }
  88. } catch (SQLException e) {
  89. e.printStackTrace();
  90. }
  91. }
  92. }

JDBC控制事务

  1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
  2. 操作:
    1. 开启事务
    2. 提交事务
    3. 回滚事务
  3. 使用Connection对象来管理事务
    • 开启事务:setAutoCommit(boolean autoCommit):调用该方法设参数为false,即开启事务
      • 在执行sql前开启事务
    • 提交事务:commit()
      • 当所有sql都执行完提交事务
    • 回滚事务:rollback()
      • 在catch中回滚事务(注意:catch 最大的Exception) ```java package a_jdbc;

import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;

public class JDBCDemo5 {

  1. public static void main(String[] args) {
  2. Connection connection = null;
  3. PreparedStatement preparedStatement1 = null;
  4. PreparedStatement preparedStatement2 = null;
  5. try {
  6. //1获取连接
  7. connection = JDBCUtils.getConnection();
  8. //开启事务
  9. connection.setAutoCommit(false);
  10. //张三 - 500
  11. String sql = "update account set balance = balance - ? where id = ?";
  12. //李四 + 500
  13. String sql2 = "update account set balance = balance + ? where id = ?";
  14. //获取执行sql对象
  15. preparedStatement1 = connection.prepareStatement(sql);
  16. preparedStatement2 = connection.prepareStatement(sql2);
  17. //4设置参数
  18. preparedStatement1.setDouble(1, 500);
  19. preparedStatement1.setInt(2, 1);
  20. preparedStatement2.setDouble(1, 500);
  21. preparedStatement2.setInt(2, 2);
  22. //5执行sql
  23. preparedStatement1.executeUpdate();
  24. int i = 3 / 0;
  25. preparedStatement2.executeUpdate();
  26. connection.commit();
  27. } catch (Exception e) {//大异常
  28. //事务的回滚
  29. try {
  30. if (connection != null) {
  31. connection.rollback();
  32. System.out.println("操作失败");
  33. }
  34. } catch (SQLException ex) {
  35. ex.printStackTrace();
  36. }
  37. e.printStackTrace();
  38. } finally {
  39. JDBCUtils.close(preparedStatement1, connection);
  40. JDBCUtils.close(preparedStatement2, connection);
  41. }
  42. }

} ```