【数据库】Java的JDBC编程(idea链接数据库)

news2024/12/23 6:06:55

目录

前言

1、Java的数据库编程:JDBC  

 2、使用JDBC(项目中导入数据库驱动包)

2.1、获取驱动包

2.2、将数据库驱动包导入Java项目中

2.3、使用JDBC编写代码

2.3.1、创建并初始化一个数据源

2.3.2、 和数据库服务器建立链接

2.3.3、构建SQL语句 

2.3.4、执行SQL语句 

2.3.4、释放资源

2.3.5、JDBC的方式插入数据(insert)

2.3.6、JDBC的方式查询数据(select)


前言

  • 我们使用的数据库有多种多样的,有MySQL、Oracle、SQL sever等等、这些数据库在开发的时候,都会提供一组程序接口(API).
  • API(Application Programming Interface):我们就举一个更简单一点的例子。软件开发员甲开发了一款软件,但是这款软件里面某些功能软件开发员乙也想使用,这个时候甲就可以把软件里面的这些功能打包成一个函数,开放给乙进行使用,乙自然也就不需要进行源码的查看,那么这个函数也就是api。我们基于api提供的功能来实现一些其他的代码。
  • JDBC存在两种写法,一种是DataSource的方式来编写的(这种是现在使用比较多的,也是这个博客中介绍的方法);还有一种是DriverManager方式编写,这个是通过反射的方式加载驱动包中的类,进一步进行后续的操作。这里更建议使用第一种方法。

1、Java的数据库编程:JDBC  

上面说到的MySQL、Oracle、SQL sever等等这些数据库,都会提供一个api接口,但是不同的数据库存在自己的数据库api,这样就导致程序员的学习成本太高。没使用一种数据库还要学习它的api。如果有一个东西可以规范这些接口,那么学习成本就降低了很多,这里我们就要说到JDBC。

  1. JDBC(Java Database Connectivity),他是一套统一的、基于Java语言的关系数据库编程接口的规范。 
  2. 对于这些数据库的api,这些数据库的厂商需要自己提供一个封装自己数据库的原生api的程序与JDBC对齐,这个程序就叫做数据库驱动包。

 

 

对于Java程序员想要进行数据库的开发,就需要在项目中导入对应的数据库驱动包,才能进行编写代码。

 这里解释一下驱动的意思:驱动这个词我们在硬件中常会听到,硬件的驱动是让操作系统认识新的硬件设备。而我们这里的数据库的驱动就是让JDBC能够认识数据库的api.

 2、使用JDBC(项目中导入数据库驱动包)

2.1、获取驱动包

三种途径 

  1. MySQL的官方网站上获取
  2. 因为MySQL是开源的所以可以在github中找
  3. maven中央仓库中获取。

maven就像我们使用手机的应用商店一样。手机上下载软件可以去官网也可以在手机的应用商店上找。maven中央仓库上面托管了各种软件程序包。进入mavem中央仓库使用链接https://mvnrepository.com

1️⃣下面这两种都可以

2️⃣ 在点击进入之后,让我们选择使用的版本,这里注意,选的版本要与我们自己装的数据库版本匹配。大版本一定要匹配,小版本可以随便选。

 

3️⃣ 点击选择需要的版本进入之后,点击jar下载即可。

 4️⃣得到jar包

 在javase的博客中说到Java程序通过.java 源文件编译成.class文件,再使用jvm来解释执行成 .class文件。我们想要发布一个程序让别人使用,我们可以将这些.class文件拷贝给对方,使用它的jvm运行就行。但是又有一个问题,当我们的程序有很多的.class 文件,这样一起拷贝给对方,总显得不太好用,这个时候我们可以使用压缩包的形式,将多个.class文件以压缩包的形式发给对方。这就是Java中最常用的发布程序的方式,形成.jar包。


2.2、将数据库驱动包导入Java项目中

❗❗❗每创建一个项目需要这样操作一次

1️⃣创建一个新的项目,并在这个项目中创建一个新的目录lib,将数据库驱动包导入

 2️⃣把lib这个目录标记成项目的库

将这个目录标记成库,idea就能识别这个目录里的jar包了。我们就可以调用里面的类来写代码了。


2.3、使用JDBC编写代码

2.3.1、创建并初始化一个数据源

数据源:我们的数据从数据库中来,所以数据源就是用来描述数据库服务器在哪里的。JDBC中用DataSource这个接口来进行描述。

这里有两种写法。

1️⃣使用DataSource接口的引用接收MysqlDataSource对象

 DataSource dataSource = new MysqlDataSource();//向上转型
((MysqlDataSource)dataSource).setUrl();//向下转型,因为DataSource中没有setUrl()这个方法,而MysqlDataSource这个类中有这个方法

2️⃣或者直接使用MysqlDataSource类来写也可以

MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setUrl();

setUrl()方法表示设置资源所在的位置。这里URL是计算机里的一个常见术语——唯一资源定位符,描述网络上的某个资源所在的位置。 这个方法的参数形式很特别

((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");

对他的参数大概了解一下

jdbc是固定的。

MySQL:是看你使用什么数据库,这是一个数据库名。

MySQL数据库是一个“客户端-服务器”结构的程序,客户端和服务器之间通过网络来通信,网络上确定主机的位置就是通过IP地址来确定的,现在我们学习的时候客户端和服务器在同一台电脑上,我们使用的是环回地址。

127.0.0.1:是环回地址,表示当前主机地址

3306:是端口号,数据库服务器默认端口就是3306.端口是用来区分应用程序的。区分将数据个那个应用程序。

people_2:表示的数据库名,我们创建了很多数据库,到底想访问哪一个。

characterEncoding:表示的是参数

utf8:字符集

SSL:是一个加密协议,此处设置成false表示不加密

 设置用户名和密码

((MysqlDataSource)dataSource).setUser("root");//设置用户的时候,都是root
((MysqlDataSource)dataSource).setPassword("991218zf");//设置密码的时候,安装数据库的时候密码是什么就是什么

上述这些步骤合起来就是设置数据源的基本操作,只有将这三个都设置了,才能够访问数据库服务器

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;

public class JDBCInsert {
    public static void main(String[] args) {
        //1、创建并初始化一个数据源
        DataSource dataSource = new MysqlDataSource();//向上转型
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("991218zf");

❗❗❗提示:上述的代码只是设置了数据源,描述数据库服务器在哪,还没有和数据库服务器真正的链接。

2.3.2、 和数据库服务器建立链接

我们使用DataSource接口的getConnection方法来实现链接。

  Connection connection = dataSource.getConnection() ;

在使用connection用来接收的时候,我们要选择第一个,第一个是JDBC提供的,第二个是MySQL数据包提供的,不能使用。

但是当我们将这个写了之后,编译器会报错。

 所以我们需要将这个异常进行处理,异常有受查异常和非受查异常

受查异常必须要显示处理,处理方式有两种

1️⃣在调用这个方法的方法体开始throws这个异常

 2️⃣或者通过try-catch处理这个异常

非受查异常可以不用显示处理。

2.3.3、构建SQL语句 

String sql = "insert into student values(1,'张三')";
PreparedStatement statement = connection.prepareStatement(sql);//进行预编译

通过第一句代码可以看见即使我们使用代码来操作数据库,还是靠sql语句,只不过是换成代码来构造sql。

❓❓❓第二句代码的作用是提前预编译sql语句,为什么要进行预编译呢?


❗❗❗数据库客户端给服务器发送一个请求时SQL字符串,服务器是可以处理的,服务器需要对SQL经行解析,理解这里的含义并执行,这对于服务器的压力就比较大了,如果是一个客户端,那没有什么问题,但是一个服务器同时可以接收很多客户端发送的请求,都是以这样的形式发送的,那么服务器的压力就非常大了。这里我们通过在客户端这里将这个SQL字符串进行预编译,转换成sql语句,这样数据库服务器的压力就非常小了。

上述构造SQL语句的这种写法存在问题。直接将代码写死了,只能插入一条数据,但是用户在使用的时候,要插入的数据肯定不止一条。我们要实现写一个插入的SQL语句,进行多条数据的插入。我们可以通过scanner类来实现让用户插入数据。

构造sql语句时存在多种写法

1️⃣比较直接的写法,通过字符串拼接的方法实现。

 String sql = "insert into student values("+id+",'"+name+"')";

这种写法是下策,它存在两个问题

  1. name这里添加单引号和双引号的位置很容易写错,可读性很低
  2. 很容易被SQL注入,sql注入是网络安全中的典型攻击方式,指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,这就导致在程序员不知情的情况下,将数据库中的数据删除或者修改。

2️⃣更好的写法,借助PreparedStatement的拼装功能来实现。

String sql = "insert into student values(?,?)";//这里的?表示的意思是占位符,表示先这个位置占住,用别的东西替换。
PreparedStatement statement = connection.prepareStatement(sql);//进行预编译
statement.setInt(1,id);//表示将第一个?替换成id的值
statement.setString(2,name);//表示将第二个?替换成name的值

  这个方法好处就是看起来更加直观了,并且可以自动的对sql注入的攻击的行为作为校验。

2.3.4、执行SQL语句 

int ret = statement.executeUpdate();
System.out.println("ret = "+ret);

这里通过executeUpdate方法把sql语句(预编译过的)发送给数据库服务器,由服务器做出响应。

executeUpdate方法返回int类型的指用ret接收,这里ret接收到的值表示为执行sql语句后影响到的行数。与数据库中的这个表示的同一个意思

 这里执行insert、delete、update这些操作的时候都使用executeUpdate这个方法。

2.3.4、释放资源

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

数据库的客户端和服务器之间通信的时候,是要消耗一定的系统资源(这里的资源不限于CPU、内存、硬盘、带宽)。 对客户端来说罢了,但是对服务器来说,同一时刻要处理很多个客户端,给一个客户端提供服务,需要消耗一定的资源,给1000个、一万个呢???这个时候消耗的资源就越来越多,服务器的资源就那么多,如何更好的利用这些资源?客户端就得省着点用(不用的时候就将资源释放)。

❗❗❗注意:释放的顺序和创建的顺序是相反的。在下面的代码中链接(connection)是先创建的,语句(statement)是后创建的。所以释放的时候statement先释放, connection后释放

2.3.5、JDBC的方式插入数据(insert)

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;

public class JDBCInsert {
    public static void main(String[] args)  throws SQLException{
        Scanner scan = new Scanner(System.in);
        //1、创建并初始化一个数据源
        DataSource dataSource = new MysqlDataSource();//向上转型
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("991218zf");
        //2、和数据库服务器建立联接
        Connection connection= dataSource.getConnection() ;
        //3、构造SQL语句
        System.out.println("请输入学生姓名:");
        String name = scan.next();
        System.out.println("请输入学生的学号:");
        int id = scan.nextInt();
        String sql = "insert into student values(?,?)";
        PreparedStatement statement = connection.prepareStatement(sql);//进行预编译
        statement.setInt(1,id);//表示将第一个?替换成id的值
        statement.setString(2,name);//表示将第二个?替换成name的值
       
        //这个打印需要加到拼接数据之后
        System.out.println(statement);

        //4、执行SQL语句
        int ret = statement.executeUpdate();
        System.out.println("ret = "+ret);
        //5、释放必要的资源
        statement.close();
        connection.close();
    }
}

 这里修改(update)和删除(delete)这两个操作在JDBC中的代码和插入相同只需要将sql语句改变一下就行。

2.3.6、JDBC的方式查询数据(select)

对查询来说,返回结果不是单纯的int了,而是ResultSet对象,表示的就是结果集合,相当于我们使用MySQL时,在客户端查询产生结果得到的临时表。

 当光标指向哪一行,就通过getXXX方法将哪一行的数据获取。

代码示例

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.*;
import java.util.logging.Logger;

public class JDBCSelect {
    public static void main(String[] args) throws SQLException{
        //1、创建并初始化数据源
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/people_2?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("991218zf");
        //2、建立链接
        Connection connection = dataSource.getConnection();
        //3、构造SQL
        String sql = "select * from student";
        PreparedStatement statement = connection.prepareStatement(sql);
        //4、执行SQL
        ResultSet resultSet = statement.executeQuery();
        //5、遍历结果集合
        while(resultSet.next()){
            //把resultSet想象成一个表格,同时这个这个表格上方有一个光标,初始情况下光标指向表的最上面
            //没调用一次next,光标往下走一行
            //当光标指向某一行的时候,就可以通过 getxxx 方法来获取到当前这行里的数据

            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            System.out.println("id = "+ id +",name = "+name);
        }
        //6、释放资源
        statement.close();
        connection.close();
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/479771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++(多态上)

目录: 1.多态的概念 2.多态的定义和实现 3.虚函数构成重写的特例 4.剖析一道非常经典的题 5.剖析多态的原理 ------------------------------------------------------------------------------------------------------------------------- 1.多态的概念 概念:通俗来说&#…

嵌入式开发--无刷电机学习2--克拉克变换

克拉克变换 首先说明,有很多方法,在数学上是等价的,比如33333*412。下面说的事情也是。 为了更简明的控制,克拉克女士提出电机控制简化的方法,即建立一个坐标系,横轴是α 纵轴是β,并将三相电…

RabbitMQ入门Demo 简单模式

出现的问题,原本4个操作,要么全部执行,要么全部不执行------->强一致性 但是现在分开了-----------最终一致性 强一致性:指在消息传递的过程中,系统会确保每个消息被精确地按照发送的顺序被传递,并且每个消息都会被正确地处理。强一致性…

重大问题,Windows11出现重大BUG

重大问题,Windows11出现重大BUG 这种Windows11操作系统出现BUG已经可以说是非常常见的,但是,今天我将代表所有微软用户,解决一个关于UI设计非常不舒服的功能 关闭多平面覆盖 事情叙述问题 微软社区解决方案自己发现的解决方案解决…

模拟比较器(Comparator)

概述 ⚫ 两个比较器,Comp1为低功耗比较器,Comp2为rail-to-rail快速比较器 ⚫比较器负端输入为vref或者IO输入,比较器正端为IO输入 ⚫ Buffer有Bypass功能,Bypass使能有效则不经过Buffer直接输入至比较器 ⚫ Buffer有1/2分压功能 ⚫…

JSON.stringfy() 和 qs.stringfy()区别 以及post/get 的参数形式

axios中post请求 application/json和 application/x-www-form-urlencoded 前端向后端传输数据时,如果是get传输,直接传在url后;如果是post传输,则在请求体body中传输。 在body中的数据格式又有两种,一种是 json 数据…

【Linux】教你用进程替换制作一个简单的Shell解释器

本章的代码可以访问这里获取。 由于程序代码是一体的,本章在分开讲解各部分的实现时,代码可能有些跳跃,建议在讲解各部分实现后看一下源代码方便理解程序。 制作一个简单的Shell解释器 一、观察Shell的运行状态二、简单的Shell解释器制作原理…

Python+Yolov8+Deepsort入口人流量统计

程序示例精选 PythonYolov8Deepsort入口人流量统计 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<PythonYolov8Deepsort入口人流量统计>>编写代码&#xff0c;代码整洁&#x…

[java]云HIS运维运营分系统功能实现(springboot框架)

运维运营分系统 一级菜单包括&#xff1a;系统运维、综合监管、系统运营 系统运维包括二级菜单&#xff1a;环境管理、应用管理、菜单管理、接口管理、任务管理、配置管理 综合监管包括二级菜单&#xff1a;综合监管 系统运营包括二级菜单&#xff1a;机构管理、药品目录管…

计算机组成原理4.2.3提高存储器访问速度的措施

提高存储器访问层次大概有三种方法 采用高速器件 采用层次结构 Cache 主存 调整主存结构 调整存储结构 单体多字系统 利用程序局部性原理&#xff0c;访问一个块 相邻的若干块都会被拿出来&#xff0c;缺点可能会碰到跳转类指令 多体并行系统 高位是体号&#xff0c;低位时地…

手动搭建高可用的 kubernetes 集群(v1.16.6)

手动搭建高可用的 kubernetes 集群(v1.16.6) 目录 手动搭建高可用的 kubernetes 集群(v1.16.6) 1、组件版本和配置策略 1.1 主要组件版本1.2 主要配置策略2、初始化系统和全局变量 2.1 集群规划2.2 初始化系统环境 2.2.1 关闭防火墙2.2.2 关闭 swap 分区2.2.3 关闭 SELinux2.2.…

【网络技术】什么是CNI

序言 你只管努力&#xff0c;其他交给时间&#xff0c;时间会证明一切。 Never look back unless you are planning to go that way. 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用…

2023年第十五届华中杯赛题A题详细版思路 新型镇静药物临床实验疗效分析与预测

2023年五一假期期间&#xff0c;数学建模竞赛就有四场&#xff0c;各种比赛各种需求应接不暇。因此&#xff0c;对于本次浅析有不足的地方欢迎大家指出。为了更好的帮助大家华中杯参赛&#xff0c;下面带来&#xff0c;A题详细版思路 问题一&#xff0c;差异性分析 文字分析&a…

JAVA基于Springboot框架的停车场管理系统开发实践和实现【附源码】

运行环境: jdk1.8idea/eclipsemaven3mysql5.6 项目技术: Java,Springboot,mybatis,mysql,jquery,html 该系统为停车场管理人员提供了对停车场中车辆&#xff0c;车位和财务的管理。操作员可以灵活地使用相关权限开展工作。在车位管理&#xff0c;车辆的停放和驶离、缴费&a…

理解Hopcroft DFA最小化算法

问题引入 在构造编译器的Scanner时&#xff0c;常见的解决方法是使用自动机技术。从文法构造出的DFA的状态数过多会影响编译器的性能。DFA中有一些状态本质上是等价的&#xff0c;我们需要一种自动化算法用于最小化DFA。 算法介绍 常见的DFA最小化算法有三种&#xff0c;分别…

栈和队列的转换

在之前的博客当中我们已经学习了栈和队列。在本次的博客当中我们就来学习一下怎么将栈和队列进行相互转换。 栈和队列的相互转换其实是两道OJ题。如果在leetcode上面刷过题的小伙伴们可能早就见过这两种数据结构的相互转换。下面我们就来分别讲解一下这两道OJ题目的编写思路。 …

为生信写的Python简明教程 | 视频2

开源生信 Python教程 生信专用简明 Python 文字和视频教程 源码在&#xff1a;https://github.com/Tong-Chen/Bioinfo_course_python 目录 背景介绍 编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Python基本语法 数…

改进YOLOv8 | 即插即用篇 | CVPR2023最新注意力 | 《BiFormer:视觉变换器与双层路由注意力》

作为视觉变换器的核心构建模块,注意力是一种强大的工具,可以捕捉长程依赖关系。然而,这种强大的功能付出了代价:计算负担和内存占用巨大,因为需要在所有空间位置上计算成对的令牌交互。一系列的研究尝试通过引入手工制作和与内容无关的稀疏性来缓解这个问题,例如将注意力…

【技术分享】防止根据IP查域名,防止源站IP泄露

有的人设置了禁止 IP 访问网站&#xff0c;但是别人用 https://ip 的形式&#xff0c;会跳到你服务器所绑定的一个域名网站上 直接通过 https://IP, 访问网站&#xff0c;会出现“您的连接不是私密连接”&#xff0c;然后点高级&#xff0c;会出现“继续前往 IP”&#xff0c;…

81. read readline readlines 读取文件的三种方法

81. read readline readlines 读取文件的三种方法 文章目录 81. read readline readlines 读取文件的三种方法1. 读取文件的三种方法2. read方法3. readline方法4. readlines方法5. 代码总结5.1 read方法读取全部内容5.2 readline方法读取一行&#xff0c;返回字符串5.3 readli…