【Java】JDBC

JDBC

JDBC是用Java语言向数据库发送SQL。

在Java里专门为JDBC提供有一个模块(java.sql),里面有一个核心模块(java.sql),在JDBC里核心的组成就是DriverManager类,以及若干接口(Connection、Statement、PreparedStatement、ResultSet)。

对于JDBC的程序数据库访问也分为如下四种形式:

  • JDBC-ODBC桥连接(淘汰了)
  • JDBC链接:一般连接本地数据库。
  • JDBC网络连接:通过特定的网络协议连接指定的数据库。
  • JDBC协议连接:自己通过编写指定的协议操纵实现数据库。

JDBC工作原理


JDBC使用流程图

基本流程代码:

import java.sql.*;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.导入驱动jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库链接对象
        String url = "jdbc:mysql://127.0.0.1:3306/transport";
        String user = "root";
        String password = "111111";
        Connection connection = DriverManager.getConnection(url,user,password);
        //4.定义SQL语句
        String sql = "insert into message values(1,'陕西西安')";
        //5.获取执行sql的对象
        Statement statement = connection.createStatement();
        //6.执行sql
        int count = statement.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        statement.close();
        connection.close();
    }
}

详解对象

DriverManager:驱动管理对象

功能:

  1. 注册驱动:告诉程序该使用哪个数据库驱动jar
  2. 获取数据库链接
    • 方法:static connection getconnection(string url,string user,string password)
    • 参数:
      • ur1:指定连接的路径
        • 语法:jdbc:mysql://ip地址(域名:端口号/款据库名称。
        • 例子:jdbc:mysql://localhost:3306/db
      • user:用户名
      • password:密码

Connection:数据库链接对象

功能:

  1. 获取执行sq1的对象
    • statement createstatement()
    • Preparedstatement preparestatement(string sql)
  2. 管理事务:
    • 开后事务:setAutocommit(boolean autocommit):调用该方法设置参数为false,即开后事务
    • 提交事务:commit()
    • 回液事务:rollback()

Statement:执行sql对象

执行sql

  1. boolean execute(stringsql):可以执行任意的sql了解
  2. int executeupdate(String sql):执行DML(insert、update、delete)语句、DOL(create,alter、drop)语句
    • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功返回值>0的则执行成功,反之,则失败。
  3. Resultset executeQuery(string sql):执行DQL(select)语句
    • 返回值:返回结果集对象。
import java.sql.*;

public class Main{
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://127.0.0.1:3306/transport";
            String user = "root";
            String password = "password";
            connection = DriverManager.getConnection(url,user,password);
            //4.定义SQL语句
            String sql = "insert into message values(1,'陕西西安')";
            //5.获取执行sql的对象
            statement = connection.createStatement();
            //6.执行sql
            int count = statement.executeUpdate(sql);
            //7.处理结果
            System.out.println(count);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //8.释放资源
            if(statement != null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Resultset:结果集对象

  • boolean next():游标向下移动一行,判断当前行是否是最后一行未尾(是否有数据),如果是,则返回false,如果不是则返回true。
  • getXxx(参数):获取数据
    • Xxx():代表数据类型如:int getInt(),string getstring()
    • 参数:
      1. int:代表列的编号,从1开始如:getstring(1)
      2. string:代表列名称。如:getInt("id")
  • 使用步骤:
    1.游标向下移动一行
    2.判断是否有数据
    3.获取数据
import java.sql.*;

public class JDBCdemo1 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://127.0.0.1:3306/transport";
            String user = "root";
            String password = "111111";
            connection = DriverManager.getConnection(url,user,password);
            //4.定义SQL语句
            //String sql = "insert into message values(2,'广东汕头')";
            String sql = "select * from Message";
            //5.获取执行sql的对象
            statement = connection.createStatement();
            //6.执行sql
            res = statement.executeQuery(sql);
            //7.处理结果
            while(true == res.next()){//让指针向下移动一行
                int id = res.getInt(1);
                String address = res.getString(2);
                System.out.println("id = " + id + " address = " + address);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //8.释放资源
            if(res != null){
                try {
                    res.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();
                }
            }
        }
    }
}

PreparedStatement:执行sql对象(功能更强大)

  1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
    1. 输入用户随便,输人密码:a' or 'a' = 'a
    2. sql:select * from user where username = 'fhdsjkf' and password = a' or 'a' = 'a
  2. 解决sq1注入问题:使用PreparedStatement对象来解决。
  3. 预编译的SQL:参数使用?作为占位符。
  4. 步骤:
    1. 导入驱动jar包
    2. 注册驱动
    3. 获取数据库连接对象
    4. 定义sq1
      • 注意:定义SQL的时候使用?占位符
      • 例子:select * from user where username = ?and password = ?;
    5. 获取执行sql语句的对象 Preparedstatement pstmt = Connection.preparestatement(string sql)
    6. 给?赋值:
      • 方法:setXxx(参数1,参数2)
      • 参数1:?的位置编号从1开始
      • 参数2:?的值
    7. 执行sql,接受返回结果,不需要传递参数。
    8. 处理结果
    9. 释放资源

JDBCUtils自己写的JDBC的工具类

import java.sql.*;

public class JDBCUtils {
    private static String url = "jdbc:mysql://127.0.0.1:3306/transport";
    private static String user = "root";
    private static String password = "111111";
    private static String driver = "com.mysql.jdbc.Driver";

    static {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接
     * @return 连接对象
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,user,password);
    }

    /**
     * 释放资源
     * @param res
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet res, Statement stmt, Connection conn){
        if(res != null){
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

测试代码:

import java.sql.*;

public class JDBCdemo1 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try {
            connection = JDBCUtils.getConnection();
            String sql = "select * from Message";
            statement = connection.createStatement();
            res = statement.executeQuery(sql);
            while(true == res.next()){
                int id = res.getInt(1);
                String address = res.getString(2);
                System.out.println("id = " + id + " address = " + address);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(res,statement,connection);
        }
    }
}

JDBC控制事务:

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

public class JDBCdemo2 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = 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对象
            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            //4. 设置参数
            pstmt1.setDouble(1,500);
            pstmt1.setInt(2,1);
    
            pstmt2.setDouble(1,500);
            pstmt2.setInt(2,2);
            //5.执行sql
            pstmt1.executeUpdate();
            // 手动制造异常
            int i = 3/0;
    
            pstmt2.executeUpdate();
            //提交事务
            conn.commit();
        } catch (Exception e) {
            //事务回滚
            try {
                if(conn != null) {
                    conn.rollback();
                }
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JDBCUtils.close(pstmt1,conn);
            JDBCUtils.close(pstmt2,null);
        }
    }
}


数据库连接池

概念:其实就是一个容器(集合),存放数据库连接的容器。

当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会得连接对象归还给容器。

好处:
1. 节约资源
2. 用户访问高效

实现:
标准接口:Datasource javax.sql包下的

方法:

  • 获取连接:getconnection();
  • 归还连接:connection.close();如果连接对象connection是从连接池中获取的,那么调用该方法,则不会关闭连接。而是归还连接.
posted @ 2020-02-06 16:20  LampsAsarum  阅读(159)  评论(0编辑  收藏  举报