JDBC编程

一、JDBC概念及其诞生原理

1.1 什么是JDBC

JDBC(Java Database Connectivity java数据库连接)是Java提供的一套用来操作数据库的API,程序员可以通过调用该 API 来操作数据库。

  1. API VS interface
    • API VS interface:应用程序编程接口(Application Programming Interface),是一个广义的概念。Java中的一个类,一个interface接口都可以理解为一个API。
    • interface:Java中的一种特殊的语法格式,interface可以作为Java中一种提供API的方式

1.2 诞生原理

  1. 不同数据库提供的不同API
    一个成熟的数据库(MySQL、Oracle、SQLServer、SQLite等)一般都会提供一些API 供程序员使用,但由于各自负责设计的工程师不同,所以各个数据库提供的API不同。所以一旦程序员要进行与数据库相关的编程,就需要学习相对应的API,十分麻烦。
  2. Java 统一口径,提出JDBC
    JDBC就是Java这边提出的一套操作数据库的API,Java要求每个数据库都遵循Java提供的JDBC API,所以Java程序员只需要了解如何调用JDBC的API即可。
  3. 其他的数据库API是如何遵循JDBC的
    每个数据库厂商提供了数据库的驱动包(一些代码),类似于翻译,将API进行转化

在这里插入图片描述

二、使用步骤

2.1 创建项目

2.2 引入MySQL的驱动包,作为项目的依赖

  1. MySQL驱动包

    • 名字:mysql-connector-java
    • 版本问题:数据库驱动包的版本要和数据库服务器的版本一致(小版本不要求,大版本要求一致),选择【jar】
  2. 关于jar包:

    • .jar 是 Java定义的一种压缩格式
    • 类似于rar这样的压缩包,主要包含了很多.class文件
    • 实用性:jar 包是Java中发布程序的一种典型方式
      要想发布程序给别人,就需要发送.class文件(由,java文件编译而来),而一旦要发送的class文件很多,就会很繁琐,此时jar包的形式可以提高发送效率
  3. 如何下载MySQL驱动包

    • Oracle 官方网站
    • GitHub/Gittee
    • 中央仓库:相当于应用商店,有人将知名的第三方库都收集起来,方便人使用
  4. 如何在项目中导入这个jar包

    • 创建一个目录lib(library 库)
    • 直接将下载好的驱动包拷贝到 lib 中
    • 选中 lib,选择 [Add as library] 。配置一下,使 idea 知道该目录放的是库文件,直接点ok即可

2.3 编写代码

(1)创建一个数据源 DataSource:

数据源:数据从哪来,以及数据库服务器在哪

DataSource dataSource = new MysqlDataSource();
  1. DataSource:由JDBC提供的一个接口
  2. MysqlDataSource:Mysql驱动包中提供的类,实现了 DataSource 的接口

(2)给DataSource对象设置属性

((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Test?characterEncoding=utf8&useSSL=false");
			
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("123456");
  1. 为什么要强转为 MysqlDataSource:为了调用这三个方法
    setUrl、setUser、setPassword 这三个方法只有MysqlDataSource子类有,父类 DataSource 没有

  2. 为什么要转型,可不可以在第一步中用“MysqlDataSource x = new MysqlDataSource(),然后用x调用3个方法:
    理论上可行,但转型主要是为了降低 Mysql驱动包 和项目代码之间的耦合关系,不让MysqlDataSource 这个类扩散到代码的其他部分,避免后续更换数据库时,有太大的成本。

  3. setUrl:

    • URL:唯一资源定位符,通常使用URL来描述网络上的一个资源的位置,mysql本体是服务器,相当于是网络上的资源
    • jdbc:mysql://127.0.0.1:3306/Test?characterEncoding=utf8&useSSL=false
      • jdbc:mysql:表示这个url是什么类型/用途的。此处意思是,【给JDBC的mysql使用的】
      • 127.0.0.1:一个特殊IP,特指自己的主机
      • 3306:端口号,用来区分主机上的应用程序(进程)。Mysql的默认端口号是3306
      • Test:数据库名
      • characterEncoding=utf8:统一字符集是utf8
      • useSSL=false:SSL指HTTPS的加密方案,不写是默认加密,不写的话有可能因为证书有问题,会连不上数据库。false不加密,true加密
  4. setUser:一般来说,大家都是【root】

  5. setPassword:安装数据库时,自己设置的密码

(3)和数据库建立连接

原理:前面只是描述了数据源信息,并未真正和数据库服务器建立联系。TCP连接

Connection connection = dataSource.getConnection();
  1. 关于 Connection 版本
    使用 JDBC 提供的(java sql),而不是com,mysql.jdbc(这是Mysql驱动包的Connection)
  2. 异常
    该操作非常容易出现异常,比如服务器不愿意建立连接,或者输入的数据库名、IP等信息有误,没有正确找到服务器等,需要手动处理。

(4)构造SQL语句

String sql = "insert into student values(1, “张三”)";
PreparedStatement statement = connection.prepareStatement(sql);
  1. 对转换过程的理解
    • 我们构造出来的 sql 语句是 String 类的,但是数据库并不认String类,但是认statement(语句),故我们需要把 String 转换成 Statement 再发给服务器执行
    • 但是我们一般不用statement,而是用 prepareStatement(预处理的语句),因为prepareStatement能让客户端先自己初步解析一下SQL,如检查构造的sql语句有没有语法问题。此时服务器就不用做这些检查了,可以在一定程度上缓解数据库服务器的压力。Statement 则是把SQL原封不动的直接发给数据库服务器。

(5)执行SQL语句

int n = statement.executeUpdate();
System.out.println("n = " + n);
  1. executQuery()
    • 本质是“读”操作, 通常用于查询语句
    • 方法执行后返回单个结果集 ResultSet,表示了一个“表格”
  2. executeUpdate()
    • 本质都是“写”操作,通常用于更新、插入、删除语句
    • 方法返回值是一个整数,指示受影响的行数,

(6)释放必要的资源:Statement、Connection、ResultSet

创建的语句对象和连接对象,都会持有一些计算机的硬件/软件上的资源,这些资源不用了就应该要及时释放。
java中虽然有“垃圾回收”机制,可以自动释放内存,但是计算机的资源又不仅仅是内存,这些其他的资源就需要手动释放(一般都是会提供close方法,专门负责释放资源的方法)

result.close()    //如果是查询操作的情况下
statement.close();
connection.close();
  1. 关闭顺序:先创建的对象,后关闭
  2. 为什么要close,java不是有“垃圾回收机制吗”
    • 创建的语句对象和连接对象,都会持有一些计算机的硬件/软件上的资源,这些资源不用了就应该要及时释放
    • java中虽然有“垃圾回收”机制,可以自动释放内存,但是计算机的资源又不仅仅是内存,这些其他的资源就需要手动释放(一般都是会提供close方法,专门负责释放资源的方法)
  3. 关闭的对象
    • PrepareStatement 和 DataSource 是都要关闭的
    • 如果是查询操作,需要创建 ResultSet 对象,相比于增删查改,还需要额外关闭这个

2.4 JDBC 与 ORM 与 Mybatis

  1. ORM 和 Mybatis 前景:JDBC 的API一套流程下来,还是十分繁琐的。因此,一些Java大佬对其进行了封装,得到了一些“数据库操作的框架”,如ORM、Mybatis等,这些可以帮助我们更简单的操作数据库
  2. JDBC 使用前景:虽然项目中不一定直接使用JDBC,往往是使用框架。但JDBC作为最基础的,是不会变的,可以在必要的时候,魔改出框架,或者创造一个新的框架。

三、示例代码

3.1 向数据表中插入一行数据

(1)不涉及动态输入

public static void main(String[] args) throws SQLException {
    DataSource dataSource = new MysqlDataSource();
    ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false");
    ((MysqlDataSource)dataSource).setUser("root");
    ((MysqlDataSource)dataSource).setPassword("123456");
    Connection connection = dataSource.getConnection();

    String sql = "insert into user values(1, '张三')";
    PreparedStatement statement = connection.prepareStatement(sql);

    int n = statement.executeUpdate();
    System.out.println(n);

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

}

(2)涉及动态输入

String sql = "insert into user values(?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
String name = scanner.next();
statement.setInt(1, id);
statement.setString(2, name);
  1. 更改【构造SQL语句部分的代码即可】
  2. String sql = “insert into student values(” + id + ", " + name + ")
    这种写法也可以达到动态输入的效果,但看起来较混乱,而且这种拼接字符串的方式,并不安全(可能会受到SQL注入攻击,黑客会通过一些特定的输入,达成对数据库攻击的效果)。综上所述,并不推荐这种写法
  3. 关于?
    是一个占位符,占据一个位置,后续PreparedStatement 会把变量的数值,代入到?中
  4. 关于数字问题:数字是几就指是第几个?,如 setInt(1, id)的1就是指,第一个?

3.2 查询数据表里的所有数据

public static void main(String[] args) throws SQLException {
    DataSource dataSource = new MysqlDataSource();
    ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/book_test?characterEncoding=utf8&useSSL=false");
    ((MysqlDataSource)dataSource).setUser("root");
    ((MysqlDataSource)dataSource).setPassword("123456");
    Connection connection = dataSource.getConnection();

    String sql = "select * from user";
    PreparedStatement statement = connection.prepareStatement(sql);

    ResultSet resultSet = statement.executeQuery();

    while (resultSet.next()){
        int id = resultSet.getInt("id");
        String name = resultSet.getString("name");
        System.out.println("id:" + id + ", name:" + name);
    }

    resultSet.close();
    statement.close();
    connection.close();
}
  1. 关于修改的地方:【构造SQL语句】 和 【关闭资源】部分
  2. ResultSet对象
    结果集,是一个“临时表”。它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法提供了对这些行中数据的访问
  3. ResultSet的遍历问题
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值