JDBC概念及API详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: JDBC概念及API详解

一、JDBC概念

JDBC就是使用Java语言操作关系型数据库的一套API


全称:(Java DataBase Connectivity) Java数据库连接

JDBC本质:

官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口


各个数据库厂商去实现这套接口,提供数据库驱动jar包


我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

JDBC好处:

各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发


可随时替代底层数据库,访问数据库的Java代码基本不变

二、JDBC快速入门步骤

0、创建工程,导入驱动jar包

93d3b2d017254c1aa289444e698fc331.png

1、注册驱动

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

2、获取连接

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

3、定义SQL语句

String sql = "SQL语句";

4、获取执行SQL对象

Statement stat = conn.createStatement();

5、执行SQL

stat.executeUpdate(sql);

6、处理返回结果


7、释放资源


代码示例:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * JDBC快速入门
 */
public class JDBCDemo1he2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
            //1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
            String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
            String username = "root";
            String password = "199884lj";
            Connection conn = DriverManager.getConnection(url, username, password);
            //3、定义sql
            String sql = "update stu set math = 90 where age = 55";
            //4、获取执行sql的对象
            Statement stat = conn.createStatement();
            //5、执行sql
            int count = stat.executeUpdate(sql);//受影响的行数
            //6、处理结束
            System.out.println(count);
            //7、释放资源
            stat.close();
            conn.close();
    }
}

三、JDBC API详解

DriverManger(驱动管理类)

管理JDBC驱动程序的基本服务。


作用:1、注册驱动        2、获取数据库连接


一、注册驱动


有此Driver文件可自动读取文件在,自动注册驱动

25f105bcd0fd47b9a8875e98702a70fe.png

350c1ec53bca4902926ab76e2bb23ea6.png

二、获取数据库连接

static Connaction         getConnaction (String usl,String user,String password)

参数


1、url:连接路径

语法:

jdbc:mysql://地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...

示例:

jdbc:mysql://127.0.0.1:3306/db1

细节:

如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则usl可以简写为:jdbc:mysql:///数据库名称?参数键值对


2、user:用户名


3、password:密码

Connection(数据库连接对象)

与特定数据库连接(会话)。执行SQL语句并在连接的上下文中返回结果。


作用:1、获取执行SQL的对象        2、管理事务


1、获取执行SQL对象


普通执行SQL对象

Statement createStatement()

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

PreparedStatement prepareStatement(sql)

执行存储过程的对象

CallableStatement prepareCall(sql)

2、事务管理


MySQL事务管理


开启事务:

BEGIN;/START  TRANSACTION;

提交事务:

COMMIT;

回滚事务:

ROLLBACK;

MySQL默认自动提交事务


JDBC事务管理:Connection接口中定义了3个对应的方法


开启事务:

setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务

提交事务:

commit()

回滚事务:

rollback()


代码示例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * JDBC API 详解:Connection
 */
public class JDBCDemo3_Connection {
    public static void main(String[] args) throws Exception {
        //1、注册驱动,在mysql的jar包下添加java.sql.Driver这个文件即可以省去手动注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3、定义sql
        String sql1 = "update stu set math = 300 where id = 1";
        String sql2 = "update stu set math = 300 where id = 2";
        //4、获取执行sql的对象
        Statement stat = conn.createStatement();
        try {
            //开启事务
            conn.setAutoCommit(false);
            //5、执行sql
            int count1 = stat.executeUpdate(sql1);//受影响的行数
            //6、处理结束
            System.out.println(count1);
            //5、执行sql
            int count2 = stat.executeUpdate(sql2);//受影响的行数
            //6、处理结束
            System.out.println(count2);
            //提交事务
            conn.commit();
        } catch (Exception e) {
            //回滚事务
            conn.rollback();
            e.printStackTrace();
        }
        //7、释放资源
        stat.close();
        conn.close();
    }
}

执行结果:

35c65e4f6b4f4a21878a694911ebdfe9.png

Statement(执行SQL语句)

用于执行静态SQL语句并返回其生成的结果的对象。


作用:执行SQL语句


int executeUpdate(sql):执行DML、DDL语句

返回值:1、DML语句影响的行数 2、DDL语句执行后,执行成功也可能返回0


ResultSet executeQuery(sql):执行DQL语句

返回值:ResultSet结果集对象


代码示例:

import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
 * JDBC API 详解:Statement
 */
public class JDBCDemo4_Statement {
    /**
     * 执行DML语句
     *
     * @throws Exception
     */
    @Test
    public void testDML() throws Exception {
        //1、注册驱动,在mysql的jar包下添加java.sql.Driver这个文件即可以省去手动注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3、定义sql
        String sql = "update stu set math = 90 where id=1";
        //4、获取执行sql的对象
        Statement stat = conn.createStatement();
        //5、执行sql
        int count = stat.executeUpdate(sql);//执行完DML语句,受影响的行数
        //6、处理结束
        //System.out.println(count);
        if (count > 0) {
            System.out.println("修改成功");
        } else {
            System.out.println("修改失败");
        }
        //7、释放资源
        stat.close();
        conn.close();
    }
    /**
     * 执行DDL语句
     * @throws Exception
     */
    @Test
    public void testDDDL() throws Exception {
        //1、注册驱动,在mysql的jar包下添加java.sql.Driver这个文件即可以省去手动注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3、定义sql
        String sql = "drop database db2";
        //4、获取执行sql的对象
        Statement stat = conn.createStatement();
        //5、执行sql
        int count = stat.executeUpdate(sql);//执行完DDL语句,可能是0
        //6、释放资源
        stat.close();
        conn.close();
    }
}

运行结果:

073bab0c78754493a0132bf327d75326.png

ResultSet(结果集对象)

ResultSet作用:


1、封装了DQL查询语句的结果


ResultSet  stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象


获取查询结果


boolean next():1、将光标从当前位置向前移动一行 2、判断当前行是否为有效行

返回值:

1、true:有效行,当前行有数据

2、false:无效行,当前行没有数据


xxx  getXxx(参数):获取数据

xxx:数据类型;如:int getInt(参数);String getString(参数

参数

int:列的编号,从1开始

String:列的名称


代码示例:

import com.itheima.pojo.Account;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
 * JDBC API 详解:Result
 */
public class JDBCDemo5_ResultSet {
    /**
     * 执行DQl语句
     * @throws Exception
     */
    @Test
    public void testResultSet() throws Exception {
        //1、注册驱动,在mysql的jar包下添加java.sql.Driver这个文件即可以省去手动注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3、定义sql
        String sql = "select * from stu";
        //4、获取statement对象
        Statement stmt = conn.createStatement();
        //5、执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //处理结果,遍历rs中的所有数值
        //6.1 光标向下移动一行,并且判断当前行是否有数据
//        while(rs.next()){
//            //6.2 获取数据 getXxx()
//            int id = rs.getInt(1);
//            String name = rs.getString(2);
//
//            System.out.println(id);
//            System.out.println(name);
//
//            System.out.println("---------------");
//        }
        while(rs.next()){
            //6.2 获取数据 getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            System.out.println(id);
            System.out.println(name);
            System.out.println("---------------");
        }
        //7、释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    /**
     * 查看account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
     * 1、定义实体类Account
     * 2、查询数据,封装到Account对象中
     * 3、将Account对象存入ArrayList集合中
     *
     *
     * @throws Exception
     */
    @Test
    public void testResultSet2() throws Exception {
        //1、注册驱动,在mysql的jar包下添加java.sql.Driver这个文件即可以省去手动注册驱动
//            Class.forName("com.mysql.jdbc.Driver");
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //3、定义sql
        String sql = "select * from account";
        //4、获取statement对象
        Statement stmt = conn.createStatement();
        //5、执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //创建集合
        List<Account> list = new ArrayList<>();
        while(rs.next()){
            Account account = new Account();
            //6.2 获取数据 getXxx()
            int id = rs.getInt("id");
            String name = rs.getString("name");
            int money = rs.getInt("money");
            //赋值
            account.setId(id);
            account.setName(name);
            account.setMoney(money);
            //存入集合
            list.add(account);
        }
        System.out.println(list);
        //7、释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

运行结果:

56c49409db614b10ad1ac9b319b7194a.png

PreparedStatement(预编译SQL语句的对象)

作用:预编译SQL语句并执行,预防SQL注入问题


SQL注入


SQL注入是通过操作输入来修改事先定义号的SQL语句,用以达到执行代码对服务器进行攻击的方法。


SQL注入演示:

import com.itheima.pojo.Account;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
 * 用户登录
 */
public class JDBCDemo6_UserLogin {
    @Test
    public void testResultSet() throws Exception {
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "199884lj";
        Connection conn = DriverManager.getConnection(url, username, password);
        //接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "2";
        String sql = "select * from tb_user where username = '" + name + "' and password = '" + pwd + "'";
        //获取stmt对象
        Statement stmt = conn.createStatement();
        //执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //判断登录是否成功
        if (rs.next()) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
        //7、释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    /**
     * 演示SQL注入
     * @throws Exception
     */
    @Test
    public void testLogin_Inject() throws Exception {
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "199884lj";
        Connection conn = DriverManager.getConnection(url, username, password);
        //接收用户输入 用户名和密码
        String name = "sdbabasdga";
        String pwd = "'or'1'='1";
        String sql = "select * from tb_user where username = '" + name + "' and password = '" + pwd + "'";
        System.out.println(sql);
        //获取stmt对象
        Statement stmt = conn.createStatement();
        //执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //判断登录是否成功
        if (rs.next()) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
        //7、释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

运行结果:

8be43ba9cce34a9e98a26f362a33ca4d.png

sql注入语句

select * from tb_user where username 'sdbabasdga' and password = ' ' or '1' = '1'

1e2f0844525140bcb55e8c58a5643664.png

1、获取PreparedStatement对象

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

2、设置参数值


PreparedStatement对象:setXxx(参数1,参数2):给?赋值

Xxx:数据类型:如setInt(参数1,参数2)

参数:

参数1:?的位置编号,从1开始

参数2:?的值


3、执行SQL

executeUpdate();/executeQuery();:不需要再传递sql


PreparedStatement好处:


1、预编译SQL,性能更高


2、防止SQL注入:将敏感字符进行转义


①PreparedStatement 预编译功能开启:useServerPrepStmts=true


②配置MySQL执行日志(重启mysql服务后生效)

log-output=FILE
general-log=1
general_log_file="D://mysql.log"
slow-query-log=1
slow_query_log_file="D://mysql_slow.log"
long_query_time=2

PrepareStatement原理:


1、在获取PreparedStatement对象时,将sql语句发送给mysql服务检查,编译(这些步骤很耗时)


2、执行时就不用再进行这些步骤,速度更快


3、如果sql模板一样,则只需要进行一次检查、编译


代码示例:

import org.junit.Test;
import java.sql.*;
/**
 * API详解 PreparedStatement
 */
public class JDBCDemo7_PreparedStatement {
    @Test
    public void testPreparedStatement() throws Exception {
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxxx";
        Connection conn = DriverManager.getConnection(url, username, password);
        //接收用户输入 用户名和密码
        String name = "zhangsan";
        String pwd = "123";
        //定义sql
        String sql = "select * from tb_user where username = ? and password = ?";
        //获取stmt对象
        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();
    }
    /**
     * PreparedStatement原理
     * @throws Exception
     */
    @Test
    public void testPreparedStatement2() throws Exception {
        //2、获取连接:如果连接的是本机mysql并且端口是默认的3306,可以简化书写
        String url = "jdbc:mysql:///db1?useUnicode=true&characterEncoding=utf8";
        String username = "root";
        String password = "xxxxxxx";
        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 = ?";
        //获取stmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
        ResultSet rs = null;
        //执行sql
        rs = pstmt.executeQuery();
        //设置?的值
        pstmt.setString(1,"aaa");
        pstmt.setString(2,"bbb");
        //执行sql
        rs = pstmt.executeQuery();
        //判断登录是否成功
        if (rs.next()) {
            System.out.println("登录成功");
        } else {
            System.out.println("登录失败");
        }
        //7、释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

运行结果:

357f9a74117246f1ac7bf26f56f69724.png

ab64bcc450fd4fc9a63da6bb3aba5db8.png

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
11月前
|
Linux 程序员 C++
Linux系统函数API----基本概念
Linux系统函数API----基本概念
64 0
|
12月前
|
SQL Java 关系型数据库
JDBC知识【JDBC API详解】第三章下篇
JDBC知识【JDBC API详解】第三章下篇
|
12月前
|
SQL Java 数据库连接
联表查询 && 索引 && 事务 && JDBC使用 &&CPU工作原理 && 线程概念 && Thread类的用法
联表查询 && 索引 && 事务 && JDBC使用 &&CPU工作原理 && 线程概念 && Thread类的用法
151 0
|
5月前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
133 7
|
2月前
|
监控 安全 测试技术
API 管理的概念是什么?Apifox 为什么值得推荐?
在互联世界中,API如同软件间的“翻译官”,让应用能相互交流、共享数据。随着API数量激增,有效管理变得至关重要。API管理确保API的质量、安全与性能,提升开发效率及用户体验。它覆盖API从设计到废弃的全过程。利用如Apifox这样的工具,可以轻松实现API的设计、测试、文档管理和模拟等。Apifox集多种功能于一体,简化工作流程,提高团队协作效率。在选择API管理工具时,Apifox以全面的功能和友好的使用体验脱颖而出,成为开发者们的优选。随着技术发展,未来API管理将更加智能化和高效。
API 管理的概念是什么?Apifox 为什么值得推荐?
|
2月前
|
XML API 数据库
商品详情数据API接口概念(sku详情图属性等全面的解析)
商品详情数据API接口是指一种编程接口(API, Application Programming Interface),它允许开发者或系统以编程方式获取商品的详细信息,包括但不限于SKU(Stock Keeping Unit,库存量单位)的详细信息、商品图片、商品属性、价格、库存状态、用户评价等。这种接口通常由电商平台、商品数据库服务商或第三方数据提供商提供,旨在帮助开发者或企业快速集成商品数据到其应用程序或系统中。
|
2月前
|
JSON 前端开发 API
一文讲清 API 接口的概念、设计和实现
总结 在这个例子中,我们创建了一个简单的Express服务器,并定义了一个/api/auth/login的POST接口来处理登录请求。我们使用body-parser中间件来解析请求体中的JSON数据,并在接口内部进行简单的用户名和密码验证。
|
4月前
|
SQL Java 数据库连接
JDBC开发之四大核心API:DriverManager Connection Statement ResultSet
JDBC开发之四大核心API:DriverManager Connection Statement ResultSet
37 1
|
5月前
|
Java 程序员 API
Java 8 Lambda 表达式和Stream API:概念、优势和实战应用
【5月更文挑战第20天】在Java 8中,Lambda 表达式和Stream API是两个非常强大的特性,它们显著改变了Java程序员处理数据和编写代码的方式。本篇技术文章将深入探讨这些特性的概念、优点,并提供实战示例,帮助理解如何有效地利用这些工具来编写更简洁、更高效的代码。
65 6
|
5月前
|
Java 关系型数据库 数据库连接
实时计算 Flink版操作报错之遇到错误org.apache.flink.table.api.ValidationException: Could not find any factory for identifier 'jdbc',该如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。