JDBC详解

25 篇文章 1 订阅
14 篇文章 3 订阅

推荐阅读: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");
Class.forName("com.mysql.cj.jdbc.Driver"); #JDBC 6版本及以后使用

注意
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之后的驱动包,可以省略注册驱动的步骤,
//        因为会自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类
//        Class.forName("com.mysql.jdbc.Driver");

        String url = "jdbc:mysql://127.0.0.1:3306/sd?useSSL=false&serverTimezone=UTC+8&useUnicode=true&characterEncoding=utf-8";
        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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值