JDBC总结1

JDBC总结1

一、概述

  • 概念:JDBC(Java DataBase Connectivity),Java数据库连接。
  • 本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包,把数据库厂商写的这套实现类,称之为数据库驱动。

结构演示:

二、使用

2.1 JDBC使用步骤

  1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
    1. 复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
    2. .右键–>Add As Library
  2. 加载驱动jar包
  3. 获取数据库连接对象 Connection
  4. 定义sql操作语句
  5. 获取执行sql语句的对象 Statement
  6. 执行sql,接受返回结果
  7. 处理结果
  8. 释放资源

代码演示:

public class JDBC {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取数据库连接对象 Connection
        String url = "jdbc:mysql://localhost:3306/mydb";
        Connection conn = DriverManager.getConnection(url, "root", "123");
        //获取操作对象
        Statement statement = conn.createStatement();
        //发送sql语句
        String sql = "insert into student(name,age,address) values('张无忌',20,'西安市')";
        //执行executeUpdate(sql) 增删改的语句
        int count = statement.executeUpdate(sql);
        //处理结果
        System.out.println(count);
        if (count > 0) {
            System.out.println("插入成功");
        } else {
            System.out.println("插入失败");
        }
        //释放资源。
        conn.close();
        statement.close();
    }
}

2.1 详解使用类

  1. Class.forName(“com.mysql.jdbc.Driver”); 加载驱动,也可以省略不写。mysql5之后的驱动jar包可以省略注册驱动的步骤。

    • 当你不写时,Driver里面存在的静态代码块会替你注册。

      static {
           try {
               DriverManager.registerDriver(new Driver());
           } catch (SQLException var1) {
               throw new RuntimeException("Can't register driver!");
           }
      }
      
  2. DriverManager:驱动管理对象

    • Java提供的管理一组 JDBC 驱动程序的基本服务。
  3. Connection:获取数据库连接。

    连接方法:

    static Connection getConnection(String url, String user, String password)

    参数:

    1. url:指定连接的路径。

      • 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
      • 例如:jdbc:mysql://localhost:3306/mydb

      提示:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称

    2. user:用户名

    3. password:密码

  4. Statement:获取数据库操作对象

  • 获取操作对象的方法:Statement createStatement()
  1. 执行sql命令

    1. boolean b = statement.execute(sql);用来执行所有的SQL语句。该方法执行SQL语句可能返回多个结果。
      • 如果第一个结果为 ResultSet 对象,则返回 true
      • 如果其为更新计数或者不存在任何结果,则返回 false
    2. int i = statement.executeUpdate(sql);用来执行DML语句,用来对表中数据进行增删改。返回值是影响的行数。
    3. ResultSet rs = executeQuery(String sql);用来执行DQL语句,用来对表进行查询。该语句返回单个 ResultSet 对象。
  2. ResultSet:结果集对象,封装查询结果

    • boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true。
    • getXxx(参数):获取数据
      • Xxx:代表数据类型。如: int getInt() ,String getString()
      • int:代表列的编号,从1开始。如:getString(1)
      • String:代表列名称。如:getDouble(“balance”)

    代码演示:

    while (resultSet.next()) {
       int id = resultSet.getInt(1);
       String content = resultSet.getString("username");
       System.out.println(id + "---" + content);
    }
    
  3. PreparedStatement:执行sql的对象

    1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题。
      • 输入用户任意,输入密码:‘a’ or ‘a’ = 'a
      • sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
    2. 解决sql注入问题:使用PreparedStatement对象来解决。
    3. 预编译的SQL:参数使用?作为占位符

    代码演示:

    public class JDBC2 {
        public static void main(String[] args) throws SQLException, ClassNotFoundException {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/mydb";
            String user = "root";
            String password = "123";
            Connection conn = DriverManager.getConnection(url, user, password);
            String sql = "select * from user where username = ? and password = ?";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setString(1, "张三");
            preparedStatement.setString(2, "123");
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                int id = resultSet.getInt(1);
                String u = resultSet.getString(2);
                String p = resultSet.getString(3);
                System.out.println(id + "---" + u + "---" + p);
            }
            //释放资源
            conn.close();
            preparedStatement.close();
            resultSet.close();
        }
    }
    

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

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

三、抽取JDBC工具类

  • 目的:简化书写
  • 使用配置文件解决传递参数的问题properties

工具类

public class JDBCUtils {
    private static String url;
    private static String username;
    private static String password;
    private static String driver;
    //想要把获取连接对象和释放资源的操作,抽取到工具类当中

    private JDBCUtils() {
    }

    static {
        try {
            Properties pro = new Properties();
            pro.load(new FileInputStream("jdbc.properties"));
            //获取数据,赋值
            url = pro.getProperty("url");
            username = pro.getProperty("username");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //获取连接对象
    public static Connection getConnection() throws SQLException {
        Connection connection = DriverManager.getConnection(url, username, password);
        return connection;
    }

    //释放资源
    public static void close(Connection conn, Statement statement, ResultSet resultSet) throws SQLException {
        if (conn != null) {
            conn.close();
        }
        if (statement != null) {
            statement.close();
        }
        if (resultSet != null) {
            resultSet.close();
        }

    }
    //释放资源
    public static void close(Connection conn, Statement statement) throws SQLException {
        if (conn != null) {
            conn.close();
        }
        if (statement != null) {
            statement.close();
        }
    }
}

配置文件

url=jdbc:mysql://localhost:3306/mydb4
username=root
password=123
driver=com.mysql.jdbc.Driver

测试类

public class MyTest2 {
    public static void main(String[] args) throws SQLException {
        Connection conn = JDBCUtils.getConnection();
        String sql = "select * from user where id>?";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setInt(1, 0);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            int id = resultSet.getInt(1);
            String content = resultSet.getString("username");
            System.out.println(id + "---" + content);
        }
        //释放资源
        JDBCUtils.close(conn,preparedStatement,resultSet);
    }
}

四、JDBC控制事物

4.1 概述

  • 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。

  • 事物的ACID特性

    • 原子性(Atomicity):是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
    • 一致性(Consistency):事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
    • 隔离性(Isolation):多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
    • 持久性(Durability):是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

4.2 事务操作和管理

  1. 操作:
    1. 开启事务
    2. 提交事务
    3. 回滚事务
  2. 使用Connection对象来管理事务
    1. 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
      • 注意:在执行sql之前开启事务
    2. 提交事务:commit()
      • 当所有sql都执行完提交事务
    3. 回滚事务:rollback()
      • 在catch中回滚事务

4.3 代码演示

模拟张三给李四借钱:

  1. 当操作正常时,借钱过程正常进行。
  2. 当存在异常时,事物启动回滚操作,避免损失。
public class JDBC1 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps1= null;
        PreparedStatement ps2= null;
        try {
            //1.获取连接
            conn = JDBCUtils.getConnection();
            //开启事务
            conn.setAutoCommit(false);
            //2.定义sql
            //2.1 张三 - 500
            String sql1 = "update account set balance = balance - ? where id = ?";
            //2.2 李四 + 500
            String sql2 = "update account set balance = balance + ? where id = ?";
            //3.获取执行sql对象
            ps1 = conn.prepareStatement(sql1);
            ps2 = conn.prepareStatement(sql2);
            //4. 设置参数
            ps1.setDouble(1,500);
            ps1.setInt(2,1);

            ps2.setDouble(1,500);
            ps2.setInt(2,2);
            //5.执行sql
            ps1.executeUpdate();
            // 手动制造异常
            int i = 3/0;
            ps2.executeUpdate();
            //提交事务
            conn.commit();
        } catch (SQLException e) {
            //事务回滚
            try {
                if(conn != null) {
                    conn.rollback();
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                JDBCUtils.close(conn,ps1);
                JDBCUtils.close(null,ps2);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值