Mysql版本:8.0.26
可视化客户端:sql yog
编译软件:IntelliJ IDEA 2019.2.4 x64
运行环境:win10 家庭中文版
jdk版本:1.8.0_361
随着人工智能与大数据的不断发展,数据库管理与运维这门技术也越来越重要,很多人都开启了学习此项技能的脚步,对于开发者来说,尤其是涉及程序与数据库的数据交互,更是重要,本文带你介绍Java程序与MySQL数据库之间的信息交互的“那些事”。
提示:以下是本篇文章正文内容,下面案例可供参考
JDBC,全称Java Database Connectivity,用官方一点的说法解释是:
它代表一组独立于任何数据库管理系统(DBMS)的API,声明在java.sql与javax.sql包中,是SUN(现在Oracle)提供的一组接口规范。由各个数据库厂商来提供实现类,这些实现类的集合构成了数据库驱动jar。
用通俗的话来讲:
JDBC就是Java程序用来连接各种数据库的API。 该API是由上述的SUN(Oracle)提供的一组公共接口+各个数据库厂商提供的驱动类构成。
JDBC API的构成关系如下图所示:
备注:本文以
MySQL数据库
作为案例
步骤:
①在你的Java项目目录下新建一个名为“jdbclibs”的文件夹,将下载好的jar包复制粘贴到刚才新建的“jdbclibs”的文件夹中。
ps:相关jar包资源我会上传至c站资源
②打开你的IDEA,找到下面的图标,点击打开,随后呈现的是“
project structure
”选项卡。
③在
project structure
选项卡中,libraries -> + -> java -> select libraries file -> 选中刚才新建的jdbclibs文件夹
④在
choose Modules
选项卡选中你要应用的模块,然后点击“ok”
⑤为单模块添加mysql驱动已完成
①打开IDEA,找到如下DE1图标,点击打开,随后呈现的是“
project structure
”选项卡。
②在
project structure
选项卡中,Modules -> 选中所有的模块 -> + -> library
③在
chose libraries
界面 选中刚才新加的jdbclibs1 jar包,选择“add selected
”
④选中后,在“
dependence
”下将新加入的jdbclibs1的scope范围切换为“Compile
”,最后点击“ok
”完成。
ps:此方法留作后期叙述
步骤:
1、模块添加了依赖的mysql驱动相关库
注意:我们在2.1中执行的操作就是给Java项目添加需依赖的mysql驱动
2、在内存中加载驱动类(可选)
org.gjt.mm.mysql.Driver
com.mysql.jdbc.Driver
com.mysql.cj.jdbc.Driver
注意:
如果你的jar包是旧版的,你必须在主方法中首行写下如下的代码,手动加载对应的的驱动类。
代码如下:
Class.forName("com.mysql.cj.jdbc.Driver");
新版的mysql驱动jar可以省略这步,旧版的mysql驱动jar必须加这一步。
why?
因为新版mysql驱动jar包下有一个META-INF/services/java.sql.Driver文件
里面有填写mysql驱动类的全名称,DriverManager会自动读取这个文件,并加载对应的驱动类
如下图所示:
小tips:
我们在后期使用数据库连接池,或者MyBatis等框架时,在配置文件中需要加这个驱动类的配置
3、连接数据库:通过DriverManager工具类获取数据库连接Connection的对象
。
此时Java程序是MySQL的一个客户端
连接数据库需要如下参数:
MySQL服务器主机的IP地址
端口号
用户名
密码
要连接的数据库名称
(这一点和使用命令行客户端、可视化工具客户端不一样),一个连接只能查看一个数据库如何把这些信息告诉给驱动类的底层呢?
通过url 传给底层,url是字符串类型,它将下面的内容包成字符串传给底层,使其构建连接
协议://主机名: 端口号/数据库名?参数名=套数值
协议是什么?
如我们司空见惯的网址,例如百度的网址http://www.baidu.com,它采用的就是http协议。
而Java程序连接数据库却是采用jdbc协议
jdbc:mysql://localhost:3306/0106db
备注:
jdbc是主协议,mysql是子协议,localhost表示连接本机的mysgl数据库,3306是端口号,0106db是一个数据库名
案例:连接数据库0106db
代码演示如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class testJdbc {
//DriverManager: 驱动管理
//getConnection: 获取连接
/*
A: 提供mysql服务所在主机的IP地址或主机名
B: 端口号
C: 用户名
D: 密码
E: 要连接的数据库名称(这一点和使用命令行客户端、可视化工具客户端不一样),一个连接只能查看一个数据库
如何把这些信息告诉底层呢?
通过url 协议://主机名: 口号/数据库名?参数名=套数值
http://www.atquigu.com
jdbc:mysql://localhost:3306/0106db
jidbc是主协议,mysql是子协议,localhost表示连接本机的mysgl数据库,3306是端口号,atguigu是一个数据库名
*/
public static void main(String[] args) throws SQLException {
//Class.forName("com.mysql.cj.jdbc.Driver"),如果在web阶段学习时,Tomcat服务器提示找不到合适的驱动类,但是代码都是对的,可以自己手动加载一下
Connection root = DriverManager.getConnection(url, "root", "123456");
System.out.println(root);
root.close();//断开连接并释放资源
}
}
原因分析: 当我们的数据库版本是MySQL8.0及以上时,url需要加参数,即serverTimezone=UTC
,否则会上述报错
代码修正如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class testJdbc {
//DriverManager: 驱动管理
//getConnection: 获取连接
/*
A: 提供mysql服务所在主机的IP地址或主机名
B: 端口号
C: 用户名
D: 密码
E: 要连接的数据库名称(这一点和使用命令行客户端、可视化工具客户端不一样),一个连接只能查看一个数据库
如何把这些信息告诉底层呢?
通过url 协议://主机名: 口号/数据库名?参数名=套数值
http://www.atquigu.com
jdbc:mysql://localhost:3306/0106db
jidbc是主协议,mysql是子协议,localhost表示连接本机的mysgl数据库,3306是端口号,atguigu是一个数据库名
*/
public static void main(String[] args) throws SQLException {
//Class.forName("com.mysql.cj.jdbc.Driver"),如果在web阶段学习时,Tomcat服务器提示找不到合适的驱动类,但是代码都是对的,可以自己手动加载一下
// String url="jdbc:mysql://localhost:3306/0106db";
/*
如果不加?serverTimezone=UTC
会报如下异常:
Excepton in thread "main" java.sql.SQLException:
The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
*/
//修正如下:
String url="jdbc:mysql://localhost:3306/0106db?serverTimezone=UTC";
Connection root = DriverManager.getConnection(url, "root", "123456");//开始连接数据库,相当于网络编程中的socket
System.out.println(root);//打印连接对象
root.close();//断开连接并释放资源
}
}
4、断开连接:使用close方法。
代码如下所示:
root.close();//断开连接并释放资源
步骤:
注意:
只要是修改数据库的数据(添加、删除、修改) ,调用的方法都是 executeUpdate()
案例:使用jdbc连接数据库0225db,在t_deployment表中插入一条数据
插入之前:
//jdbc实现插入数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class testInsert {
public static void main(String[] args) throws SQLException {
//开始连接数据库,相当于网络编程中的socket
String url="jdbc:mysql://localhost:3306/0225db?serverTimezone=UTC";
Connection root = DriverManager.getConnection(url, "root", "123456");
String sql="INSERT INTO t_department VALUES(7,'保安部','负责安保巡逻工作')";
PreparedStatement pst = root.prepareStatement(sql);//把sql语句装进去;相当于通过PreparedStatement对象把sql发送给MySQL服务端
int len=pst.executeUpdate();//len代表的是影响的记录数,真正发送数据的是pst.executeUpdate()
/*
int len = pst.executeUpdate()
执行操作增删改,并返回一个int型数值,表示同步更新的记录条数
*/
System.out.println(len>0?"添加成功":"添加失败");
//释放资源
pst.close();
root.close();
}
}
步骤:
注意:
只要是修改数据库的数据(添加、删除、修改) ,调用的方法都是 executeUpdate()
案例:使用jdbc连接数据库0225db,在t_deployment表中删除刚才插入的一条数据
删除之前:
//jdbc实现删除数据
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class testDelete {
public static void main(String[] args) throws SQLException {
//开始连接本机的MySQL服务端
String url="jdbc:mysql://localhost:3306/0225db?serverTimezone=UTC";
Connection root = DriverManager.getConnection(url, "root", "123456");
String sql="delete from t_department where did=7";
PreparedStatement pst = root.prepareStatement(sql);//把sql语句装进PreparedStatement对象中,准备发送
int len = pst.executeUpdate();//真正发送sql语句
/*
int len = pst.executeUpdate()
执行操作增删改,并返回一个int型数值,表示同步更新的记录条数
*/
System.out.println(len>0?"删除成功":"删除失败");
//释放资源
pst.close();
root.close();
}
}
步骤:
注意:
只要是修改数据库的数据(添加、删除、修改) ,调用的方法都是 executeUpdate()
案例:使用jdbc连接数据库,将did为7的dname的值改为安保部
修改之前:
代码修改如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//jdbc实现更新数据
public class testUpdate {
public static void main(String[] args) throws SQLException {
//开始连接本机的MySQL服务端
String url="jdbc:mysql://localhost:3306/0225db?serverTimezone=UTC";
Connection root = DriverManager.getConnection(url, "root", "123456");
String sql="UPDATE t_department SET dname='安保部' WHERE did=7";
PreparedStatement pst = root.prepareStatement(sql);//把sql语句装进PreparedStatement对象中,准备发送
int len = pst.executeUpdate();//真正发送sql语句
/*
int len = pst.executeUpdate()
执行操作增删改,并返回一个int型数值,表示同步更新的记录条数
*/
System.out.println(len>0?"更新成功":"更新失败");
//释放资源
pst.close();
root.close();
}
}
步骤:
注意:
只要是修改数据库的数据(添加、删除、修改) ,调用的方法都是 executeUpdate()
执行查询数据库的数据,调用的方法是executeQuery(),它的返回值类型ResultSet结果集
while(rs.next()){
//遍历结果集的每一行
变量=rs.getXXX(字段名/字段列表)
}
案例:使用jdbc连接数据库,查询t_employee表中的所有信息
import java.sql.*;
//jdbc实现查询数据
public class testSelect {
public static void main(String[] args) throws SQLException {
//开始连接本机的MySQL服务端
String url="jdbc:mysql://localhost:3306/0225db?serverTimezone=UTC";
Connection root = DriverManager.getConnection(url, "root", "123456");
String sql="select * from t_department";
PreparedStatement pst = root.prepareStatement(sql);//把sql语句装进PreparedStatement对象中,准备发送
ResultSet resultSet = pst.executeQuery();//返回一个结果集;真正发送sql
/*
//如果查询之前我很清楚表中字段的数据类型,就可以使用如下代码
while (resultSet.next()){ //相当于Collection系列集合得到的iterator迭代器的hashnext()方法
int did=resultSet.getInt("did");//"did"是数据库0225db下t_department表的字段名did
String dname=resultSet.getString("dname");//数据库中的字段名
String description=resultSet.getString("description");//数据库中的字段名
System.out.println(did+"\t"+dname+"\t"+description+"\t");
}
*/
//如果我不是很清楚表中字段的数据类型,使用下列的代码写法,这样做是为了屏蔽数据库字段的数据类型的差异
while (resultSet.next()){ //相当于Collection系列集合得到的iterator迭代器的hashnext()方法
Object did=resultSet.getObject(1);//数据库0225db下t_department表的字段的序号为1
Object dname=resultSet.getObject(2);//数据库中的字段序号为2
Object description=resultSet.getObject(3);//数据库中的字段序号为3
System.out.println(did+"\t"+dname+"\t"+description+"\t");
}
//释放资源
resultSet.close();
pst.close();
root.close();
}
}