当前位置:网站首页>JDBC详解

JDBC详解

2022-07-06 11:22:00 斯文~

推荐阅读:Druid 数据库连接池详解

快速入门

Java操作数据库的流程
1.编写Java代码;
2.Java代码将SQL发送到MySQL服务端;
3.MySQL服务端接收到SQL语句并执行该SQL语句;
4.将SQL语句执行的结果返回给Java代码;

JDBC具体实现流程
1.创建工程,导入驱动jar包;
在这里插入图片描述
2.注册驱动:Class.forName("com.mysql.jdbc.Driver");
3.获取连接: Connection conn = DriverManager.getConnection(url, username, password);Java代码需要发送SQL给MySQL服务端,就需要先建立连接;
4.定义SQL语句:String sql = “update…” ;
5.获取执行SQL对象:执行SQL语句需要SQL执行对象,而这个执行对象就是Statement对象,Statement stmt = conn.createStatement()
6.执行SQL:stmt.executeUpdate(sql);
7.处理返回结果;
8.释放资源;


API详解

DriverManager 获取连接

注册驱动

DriverManager(驱动管理类)作用:注册驱动;

在Java文档中static void registerDriver(Driver driver)方法是用来注册驱动的。

查询MySQL提供的Driver类,可以看到该方法是在静态代码块中实现的。代码如下:
在这里插入图片描述
在该类中的静态代码块中已经执行了 DriverManager 对象的registerDriver() 方法进行驱动的注册了,那么我们只需要加载 Driver 类,该静态代码块就会执行。而Class.forName("com.mysql.jdbc.Driver"); 就可以加载Driver 类。

因此连接数据库前,我们只需执行以下代码即可。

Class.forName("com.mysql.jdbc.Driver");

注意
MySQL 5之后的驱动包,可以省略注册驱动的步骤,其会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类。

获取数据库连接

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

参数说明

url:连接路径

语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
示例:jdbc:mysql://127.0.0.1:3306/db1

* 如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称?参数键值对
* 配置 useSSL=false 参数,禁用安全连接方式,解决警告提示

user:用户名
poassword :密码

代码示例

public class connect {
    
    public static void main(String[] args) throws Exception {
    
// MySQL 5之后的驱动包,可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");

        String url="jdbc:mysql://127.0.0.1:3306/sd?useSSL=false";
        String user="root";
        String password="root";

        try {
    
            Connection conn= DriverManager.getConnection(url,user,password);
            System.out.println("连接成功!");
        } catch (SQLException e) {
    
            throw new RuntimeException(e);
        }
    }
}

Connection 获取对象

获取执行 SQL 的对象

1.普通执行SQL对象

Statement createStatement()

2.预编译SQL的执行SQL对象:防止SQL注入

PreparedStatement prepareStatement(sql)

该方法是常用方法,可以防止SQL注入,会在本文后面详细讲解 。

3.执行存储过程的对象

CallableStatement prepareCall(sql)

通过这种方式获取的 CallableStatement 执行对象是用来执行存储过程的,但存储过程在MySQL中不常用。

代码示例

public class connect {
    
    public static void main(String[] args) throws Exception {
    
// MySQL 5之后的驱动包,可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://127.0.0.1:3306/sd?useSSL=false";
        String user = "root";
        String password = "root";
        
        Connection conn = DriverManager.getConnection(url, user, password);

        String sql="update course set cname='C++' where cno=1";
        
        Statement stmt=conn.createStatement();

        int count=stmt.executeUpdate(sql);
        System.out.println(count);
    }
}

事务管理

开启事务: BEGIN; 或者 START TRANSACTION;
提交事务: COMMIT;
回滚事务:ROLLBACK;

MySQL默认是自动提交事务

开启事务

void setAutoCommit(boolean autoCommit)

参与autoCommit 表示是否自动提交事务,true表示自动提交事务,false表示手动提交事务。而开启事务需要将该参数设为false。

提交事务

void commit()

回滚事务

void rollback()

代码示例

public class connect {
    
    public static void main(String[] args) throws Exception {
    
// MySQL 5之后的驱动包,可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://127.0.0.1:3306/sd?useSSL=false";
        String user = "root";
        String password = "root";

        Connection conn = DriverManager.getConnection(url, user, password);

        String sql1="update course set cname='Java' where cno=1";
        String sql2="update course set cname='Java' where cno=2";

        Statement stmt=conn.createStatement();

        try {
    
            int count1=stmt.executeUpdate(sql1);
            System.out.println(count1);

            int i=1/0; // 人为制造异常,以观察归滚操作

            int count2=stmt.executeUpdate(sql2);
            System.out.println(count2);

            //若没有异常 ,则提交所有改动,数据库更新
            conn.commit();
        } catch (SQLException e) {
    
            //若存在异常,则撤销此前的所有操作(sql1的更新操作)
            conn.rollback();
        }

    }
}

Statement 执行语句

Statement对象的作用就是用来执行SQL语句。而针对不同类型的
SQL语句使用的方法也不一样。

执行DDL、DML语句:executeUpdate

int executeUpdate(String sql)

执行DQL语句:executeQuery

ResultSet executeQuery(String sql)

该方法涉及到了 ResultSet 对象,会在本文后面详细讲解。

代码示例

public class connect {
    
    public static void main(String[] args) throws Exception {
    
// MySQL 5之后的驱动包,可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://127.0.0.1:3306/sd?useSSL=false";
        String user = "root";
        String password = "root";

        Connection conn = DriverManager.getConnection(url, user, password);

        String sql1 = "update st set age=15 where name='Tom'";
        String sql2 = "select * from st";

        Statement stmt = conn.createStatement();

        //执行DDL、DML语句
        int c = stmt.executeUpdate(sql1);
        System.out.println(c);

        System.out.println("------------------");

        //执行DQL语句:查询
        ResultSet rs = stmt.executeQuery(sql2);
        while (rs.next()) {
    
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println(id + " " + name + " " + age);
        }

    }
}

运行结果
在这里插入图片描述

ResultSet 处理返回结果

概述

ResultSet封装了SQL查询语句的结果,执行了DQL语句后就会返回该对象。

ResultSet executeQuery(String sql)

ResultSet对象提供了操作查询结果数据的方法,如下:

方法说明
boolean next()将光标下移一行后并判断新的行是否有效,true有效、false无效

获取数据
Xxx getXxx(参数);
Xxx:要查询的数据类型,如getInt(参数);
参数
用列的名称查询的话是传String类型,如getString("name");
用列的索引查询的话,传int类型,表的第一列索引为1,如getString(1);

代码示例

public class connect {
    
    public static void main(String[] args) throws Exception {
    
// MySQL 5之后的驱动包,可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://127.0.0.1:3306/sd?useSSL=false";
        String user = "root";
        String password = "root";

        Connection conn = DriverManager.getConnection(url, user, password);

        String sql = "select * from st";

        Statement stmt = conn.createStatement();

        System.out.println("---------用列的名称查询----------");
        ResultSet rs = stmt.executeQuery(sql);
        while (rs.next()) {
    
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            System.out.println(id + " " + name + " " + age);
        }

        System.out.println("---------用列的索引查询----------");

        ResultSet rs1 = stmt.executeQuery(sql);
        while (rs1.next()) {
    
            int id = rs1.getInt(1);
            String name = rs1.getString(2);
            int age = rs1.getInt(3);
            System.out.println(id + " " + name + " " + age);
        }

    }
}

在这里插入图片描述


PreparedStatement 防注入

PreparedStatement作用:预编译SQL语句并执行,预防SQL注入问题。它是通过将特殊字符进行转义实现的。

获取 PreparedStatement 对象

PreparedStatement prepareStatement(String sql)
// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(1,"user");
pstmt.setInt(2,123456);

设置参数值
PreparedStatement对象:setXxx(参数,值):给 ? 赋值
Xxx:数据类型 ; 如 setInt(1,10);
参数:?的位置编号,从1开始;
**值:**给参数所赋的值

执行SQL语句

调用executeUpdate() 和 executeQuery()这两个方法时不需要再传递SQL语句,因为获取SQL语句执行对象时已经对SQL语句进行预编译了。

public void testPreparedStatement() throws  Exception {
    
    //2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
    String url = "jdbc:mysql:///db1?useSSL=false";
    String username = "root";
    String password = "1234";
    Connection conn = DriverManager.getConnection(url, username, password);

    // 接收用户输入 用户名和密码
    String name = "zhangsan";
    String pwd = "' or '1' = '1";

    // 定义sql
    String sql = "select * from tb_user where username = ? and password = ?";
    // 获取pstmt对象
    PreparedStatement pstmt = conn.prepareStatement(sql);
    // 设置?的值
    pstmt.setString(1,name);
    pstmt.setString(2,pwd);
    // 执行sql
    ResultSet rs = pstmt.executeQuery();
    // 判断登录是否成功
    if(rs.next()){
    
        System.out.println("登录成功~");
    }else{
    
        System.out.println("登录失败~");
    }
    //7. 释放资源
    rs.close();
    pstmt.close();
    conn.close();
}
原网站

版权声明
本文为[斯文~]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_52341477/article/details/125604310

随机推荐