JDBC入门基础

目录

JDBC的基本概念

快速入门(基本步骤)

创建数据库

注册驱动(可以省略不写)

获取连接对象

获取执行SQL语句的对象

编写SQL语句,并执行,以及接收返回的结果

处理结果,遍历结果集和

释放资源(先开后关的原则)

运行结果

核心理解

注册驱动

Connection

Statement

PrepareStatement

Statement和PreparedStatement

共同点

不同点

ResultSet

基于PreparedStatement实现CRUD

查询单行单列

查询单行多列

查询多行多列

新增

修改

删除


JDBC的基本概念

JDBC是Java语言中用于连接和操作数据库的一套API,他为Java应用程序提供了与关系型数据库进行交互的能力。通过使用JDBC API,开发者可以编写与平台无关的数据库操作代码,实现对多种数据的访问和管理。

JDBC的作用

JDBC允许Java应用程序通过调用其API与数据库进行通信,执行如创建连接、执行SQL语句、处理事务、获取元数据等操作

JDBC的组成

JDBC由一系列接口和类组成,包括驱动管理、连接、语句以及结果集等部分。其中,Connection接口代表与数据库的连接;Statement接口用于发送SQL语句到数据库;ResultSet接口代表SQL查询的结果集

JDBC的原理

JDBC定义了一套规范接口,各个数据库厂商遵循这套规范提供各自的JDBC驱动程序。应用程序通过加载和使用这些驱动程序,就可以与相应的数据库进行通信。

JDBC的使用

使用使用JDBC的基本步骤包括加载JDBC驱动、建立数据库连接、创建语句对象、执行SQL语句以及处理结果集。此外,还需要正确关闭所有资源以避免资源泄漏。

JDBC的功能

除了基本的数据库操作外,JDBC还支持批处理操作、事务处理和元数据操作等高级功能。参数化查询则可以通过PreparedStatement对象来实现,以提高安全性和效率。

JDBC的扩展

随着技术的发展,JDBC也在不断进化,以支持更多的数据库特性和提高性能。例如,JDBC 4.0引入了对XML的支持,JDBC 4.1和4.2版本则增加了对自动关闭资源和数据库元数据访问的改进。

快速入门(基本步骤)

创建数据库

CREATE DATABASE example;

use example;

create table t_emp
(
    emp_id     int auto_increment comment '员工编号' primary key,
    emp_name   varchar(100)  not null comment '员工姓名',
    emp_salary double(10, 5) not null comment '员工薪资',
    emp_age    int           not null comment '员工年龄'
);

insert into t_emp (emp_name,emp_salary,emp_age)
values  ('andy', 777.77, 32),
        ('大风哥', 666.66, 41),
        ('康师傅',111, 23),
        ('Gavin',123, 26),
        ('小鱼儿', 123, 28);

注册驱动(可以省略不写)

//类加载
Class.forName("com.mysql.cj.jdbc.Driver");
//手动注册
DriverManager.registerDriver(new Driver());

获取连接对象

方式一、
String url="jdbc:mysql://localhost:3306/jdbc1";
String username="root";
String password="227577";
Connection connection = DriverManager.getConnection(url, username, password);

方式二、
Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "用户名", "密码");

获取执行SQL语句的对象

Statement statement = connection。createStatement();

编写SQL语句,并执行,以及接收返回的结果

String sql ="sql执行语句";
ResultSet resultSet = statement.executeQuery(sql);

处理结果,遍历结果集和

while(resultSet.next()){
            int empId = resultSet.getInt("emp_id");
            String empName = resultSet.getString("emp_name");
            double empSalary = resultSet.getDouble("emp_salary");
            int empAge = resultSet.getInt("emp_age");
            System.out.println(empId+"\t"+empName+"\t"+empSalary+"\t"+empAge);
        }

释放资源(先开后关的原则)

resultSet.close();
statement.close();
connection.close();

运行结果

核心理解

注册驱动

类加载的方式

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

手动注册

DriverManager.registerDriver(new Driver());

注意选择cj.jdbc的版本

Connection

Connection是JDBC API的重要接口,用于建立与数据库据的通信通道。

建立连接时,需要指出数据库URL,用户名,密码参数

String url = "jdbc:mysql://ip地址:端口号/数据库名称?参数键值对1&参数键值对2"

提供commit和rollback方法,用于提交事务和回滚事务。

可以创建Statement对象,用于执行SQL语句并与数据库进行交互。

必须先获取Connection对象,在使用完毕后,释放资源。

Statement

Statement接口用于执行SQL语句并与数据库进行交互。他是JDBC API的一个重要接口,通过Statement对象,可以向数据库发送SQL语句并执行结果

结果可以是一个或多个结果

增删改:受影响行数单个结果

查询:单行单列,多行多列,单行多列等结果

Statement接口在执行SQL语句时,会产生SQL注入攻击问题

当使用Statement执行动态构建SQL查询时,往往需要将查询条件与SQL语句拼接在一起,直接将参数和SQL语句一并生成,让SQL的查询条件始终为true得到的结果

PrepareStatement

PreparedStatement是Statement接口的子接口,用于执行预编译的SQL查询,作用如下

**1、预编译SQL语句:**在创建PreparedStatement时,就会预编译SQL语句,也就是SQL语句已经固定

2、防止SQL注入: PreparedStatement支持参数化查询,将数据作为参数传递到SQL语句中,采用"?"占位符的方式,将传入的参数用一堆单引号包裹起来,无论传递什么都作为值。有效的防止传入关键字或值导致的SQL注入问题

3、性能提升:PrepareStatement是预编译SQL语句,同时SQL语句多次执行的情况下,可以复用,不必每次重新编译和解析。

Statement和PreparedStatement

共同点

**基本功能:**Statement和PreparedStatement都用于执行SQL语句,包括查询,更新,插入和删除等操作。

**API的一部分:**他们都是JDBC API的一部分,用于与关系型数据库进行交互

**结果处理:**无论是Statement和PreparedStatement,执行查询后都会生成一个ResultSet对象,该对象包含查询的结果集。

不同点

1、参数化查询

PreparedStatement:支持参数化查询,可以使用占位符**"?"**代替具体的值,通过setXXX方法为占位符赋值,提高了灵活性和安全性。

Statement:不支持参数查询,需要手动拼接SQL语句,容易受到SQL注入攻击的影响。

2、性能对比

PreparedStatement:预编译SQL语句,对于多次执行的语句,性能更高,因为它减少了数据库解析SQL的负担。

Statement:每次执行都需要数据库重新编译SQL语句,对于重复执行的操作效率较低。

3、安全性

PreparedStatement:通过参数化查询防止SQL注入,提高代码的安全性。

Statement:直接执行字符串形式的SQL语句,如果没有进行严格的输入验证,可能会受到SQL注入攻击。

4、资源占用

PreparedStatement:由于预编译的特性,会占用更多的数据库资源,尤其是在处理大量不同的SQL语句时。

Statement:资源占用较少,因为不需要预编译SQL语句。

5、适用场景

PreparedStatement:适用于需要多次执行的带参数的SQL语句,例如批量更新或插入操作。

Statement:适用于执行次数较少且不带参数的静态SQL语句。

6、批处理能力

PreparedStatement:支持批处理,可以大幅度提高批量操作的性能。

Statement:虽然也支持批处理,但由于缺乏预编译的优势,性能提升不如PreparedStatement明显。

ResultSet

ResultSet是JDBC API中的一个接口,用于表示从数据库中执行查询语句所返回的结果集。它提供了以重用于遍历和访问查询结果的方式。

遍历结果:ResultSet可以用于next()方法将游标移动到结果集的下一行,逐行遍历数据库查询的结果,返回值为boolean类型,true代表有下一行结果,false则代表没有。

获取单列结果:可以通过getXXX的方式获取单列的数据,该方法为重载方法,支持索引和列名进行获取。

遍历代码如下

while(resultSet.next()){
            int empId = resultSet.getInt("emp_id");
            String empName = resultSet.getString("emp_name");
            double empSalary = resultSet.getDouble("emp_salary");
            int empAge = resultSet.getInt("emp_age");
            System.out.println(empId+"\t"+empName+"\t"+empSalary+"\t"+empAge);
        }

基于PreparedStatement实现CRUD

查询适用:executeQuery;新增、修改、删除使用:executeUpdate

查询单行单列

public void test1() throws Exception {
        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");
        //预编译SQL语句得到PreparedStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("select count(*) as count from t_emp");
        //执行SQL语句,获取结果
        ResultSet resultSet = preparedStatement.executeQuery();
        //处理结果:(如果自己明确一定只有一个结果,那么resultSet最少要做一次next的判断,才能拿到我们要的列的结果。
        if(resultSet.next()){
            int count = resultSet.getInt("count");
            System.out.println(count);
        }
        /*while(resultSet.next()){
            int count = resultSet.getInt("count");
            System.out.println(count);
        }*/
        //释放资源:
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

查询单行多列

public void test2() throws Exception {
        //注册驱动:(省略不写)

        //获取链接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");
        //预编译sql语句获取PrepareStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_emp where emp_id =?");
        //为占位符赋值,然后执行,并接收结果
        preparedStatement.setInt(1,5);
        ResultSet resultSet = preparedStatement.executeQuery();
        //处理结果
        while(resultSet.next()){
            int empId = resultSet.getInt("emp_id");
            String empName = resultSet.getString("emp_name");
            double empSalary = resultSet.getDouble("emp_salary");
            int empAge = resultSet.getInt("emp_age");
            System.out.println(empId+" "+empName+" "+empSalary+" "+empAge);
        }
        //资源释放
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

查询多行多列

public void test3() throws Exception {
        //注册驱动(省略)
        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");
        //预编译sql语句获取prepareStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_emp where emp_age > ?");
        //为占位符赋值,然后执行,并接收结果
        preparedStatement.setInt(1,25);
        ResultSet resultSet = preparedStatement.executeQuery();
        //处理结果
        while(resultSet.next()){
            int empId = resultSet.getInt("emp_id");
            String empName = resultSet.getString("emp_name");
            double empSal = resultSet.getDouble("emp_salary");
            int empAge = resultSet.getInt("emp_age");
            System.out.println(empId+" "+empName+" "+empSal+" "+empAge);
        }
        //释放资源
        resultSet.close();
        preparedStatement.close();
        connection.close();
    }

新增

public void test4() throws Exception {
        //注册驱动(可不写)

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");
        //预编译sql语句获取prepareStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("insert into t_emp (emp_name,emp_salary,emp_age) values(?,?,?)");
        //执行,并接收结果
        preparedStatement.setString(1,"rose");
        preparedStatement.setDouble(2,345.67);
        preparedStatement.setInt(3,28);
        int result = preparedStatement.executeUpdate();
        //根据受影响多行数,做判断,得到成功或失败
        if(result>0){
            System.out.println("成功!");
        }else{
            System.out.println("失败!");
        }
        //释放资源
        preparedStatement.close();
        connection.close();
    }

修改

public void test5() throws Exception {
        //注册驱动

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");
        //预编译sql语句,获取prepareStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("update t_emp set emp_salary = ? where emp_id =?");
        //执行并接收结果
        preparedStatement.setDouble(1,888.88);
        preparedStatement.setInt(2,6);
        int result = preparedStatement.executeUpdate();
        //处理结果
        if(result>0){
            System.out.println("成功!");
        }else{
            System.out.println("失败!");
        }
        //释放资源
        preparedStatement.close();
        connection.close();
    }

删除

public void Test6() throws Exception {
        //注册驱动

        //获取连接
        Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc1", "root", "227577");

        //预处理sql语句,获取prepareStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement("delete from t_emp where emp_id = ?");
        preparedStatement.setDouble(1,6);
        //执行并接收结果
        int result = preparedStatement.executeUpdate();
        //处理结果
        if(result > 0){
            System.out.println("成功!");
        }else{
            System.out.println("失败!");
        }
        //释放资源
        preparedStatement.close();
        connection.close();
    }
相关推荐
太空漫步112 小时前
android社畜模拟器
android
海绵宝宝_5 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
凯文的内存6 小时前
android 定制mtp连接外设的设备名称
android·media·mtp·mtpserver
天若子6 小时前
Android今日头条的屏幕适配方案
android
林的快手8 小时前
伪类选择器
android·前端·css·chrome·ajax·html·json
望佑8 小时前
Tmp detached view should be removed from RecyclerView before it can be recycled
android
xvch10 小时前
Kotlin 2.1.0 入门教程(二十四)泛型、泛型约束、绝对非空类型、下划线运算符
android·kotlin
人民的石头14 小时前
Android系统开发 给system/app传包报错
android
yujunlong391915 小时前
android,flutter 混合开发,通信,传参
android·flutter·混合开发·enginegroup
rkmhr_sef15 小时前
万字详解 MySQL MGR 高可用集群搭建
android·mysql·adb