[TOC]
## 一、JDBC连接
使用JDBC时,我们先了解什么是Connection。Connection代表一个JDBC连接,它相当于Java程序到数据库的连接(通常是TCP连接)。打开一个Connection时,需要准备URL、用户名和口令,才能成功连接到数据库。
URL是由数据库厂商指定的格式,例如,MySQL的URL是:
<br>
~~~
jdbc:mysql://<hostname>:<port>/<db>?key1=value1&key2=value2
~~~
<br>
假设数据库运行在本机`localhost`,端口使用标准的`3306`,数据库名称是`learnjdbc`,那么URL如下:
~~~
jdbc:mysql://localhost:3306/learnjdbc?useSSL=false&characterEncoding=utf8
~~~
<br>
后面的两个参数表示不使用SSL加密,使用UTF-8作为字符编码(注意MySQL的UTF-8是`utf8`)。
要获取数据库连接,使用如下代码:
```
package day07;
import java.sql.DriverManager;
public class day01jdbc {
public static void main(String args[]){
// JDBC连接的url,不同数据库有不同的格式
String JDBC_URL = "jdbc:mysql://localhost:3306/go_gin_test";
String JDBC_USER = "root";
String JDBC_PASSWORD = "12345";
// 获得连接
Connection conn = DriverManager.getConnection(JDBC_URL,JDBC_USER,JDBC_PASSWORD);
// 访问数据库
// 关闭连接
conn.close();
}
}
```
<br>
<br>
核心代码是`DriverManager`提供的静态方法`getConnection()`。`DriverManager`会自动扫描classpath,找到所有的JDBC驱动,然后根据我们传入的URL自动挑选一个合适的驱动。
因为JDBC连接是一种昂贵的资源,所以使用后要及时释放。使用`try (resource)`来自动释放JDBC连接是一个好方法:
```
try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD)) {
...
}
```
<br>
<br>
## 二、JDBC中常用类和接口
连接到数据库(Connection)、建立操作指令(Statement)、执行查询指令(executeQuery)、获得查询结果(ResultSet)等。
### 1、驱动程序管理类(DriverManager)
DriverManager类是JDBC的管理类,作用于用户和驱动程序之间。它跟踪在可用的驱动程序,并在数据库和相应驱动程序之间建立连接。另外,DriverManager类也处理诸如驱动程序登陆时间限制及登录和跟踪消息的显示事务。对于简单的应用程序,一般程序员需要在此类中直接使用唯一的方法时DriverManager.getConnection()。该方法将建立与数据库的链接。JDBC允许用户调用DriverManager的方法getDriver()、getDrivers()和registerDriver()及Driver的方法connect().
### 2、声明类(Statement)
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement对象,它们都作为在给定链接上执行SQL语句的包容器:Statement、PreparedStatement(它从Statement继承而来)和CallableStatement(它从PreparedStatement继承而来)。它们都专用于发送特定类型的SQL语句:
(1)Statement对象用于执行不带参数的简单的SQL语句;Statement接口提供了执行语句和获取结果的基本方法。
(2)PerparedStatement对象用于执行带或不带IN参数的预编译SQL语句;PeraredStatement接口添加处理IN参数的方法;
(3)CallableStatement对象用于执行对数据库已存储过程的调用;CallableStatement添加处理OUT参数的方法。
#### Statement提供了许多方法,最常用的方法如下:
(1)execute()方法:运行语句,返回是否有结果集。
(2)executeQuery()方法:运行查询语句,返回ReaultSet对象。
(3)executeUpdata()方法:运行更新操作,返回更新的行数。
(4)addBatch()方法:增加批处理语句。
(5)executeBatch()方法:执行批处理语句。
(6)clearBatch()方法:清除批处理语句。
### 3、数据库连接类 (Connection)
Connection对象代表与数据库的链接。连接过程包括所执行的SQL语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与很多数据库有连接。打开连接与数据库建立连接的标准方法是调用DriverManager.getConnection()方法。
String url="jdbc:mysql://127.0.0.1:3306/imooc";
String user="root";
String password="tiger";
DriverManager.getConnection(url,user,password);
### 4、结果集合类 (ResultSet)
ResultSet包含符合SQL语句中条件的所有行记录,并且它通过一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。ResultSet.next()方法用于移动到ResultSet中的下一行,使下一行成为当前行。
5、JDBC编程步骤
(1)加载驱动程序:Class.forName(driverClass)
加载mysql驱动:Class.forName("com.mysql.jdbc.Driver");
加载oracle驱动:Class.forName("oracle.jdbc.driver.OracleDriver");
(2)获得数据库连接
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/imooc",user,password);
DriverManager.gerConnection(URL,user,password);
(3)创建Statement对象:conn.createStatement();
(4)向数据库发送SQL命令
(5)处理数据库的返回结果(ResultSet类)
<br>
**案例演示:**
```
package day07;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
import org.apache.log4j.Logger;
public class day01jdbc {
// MySQL 8.0 以下版本 - JDBC 驱动名及数据库 URL
// static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
// static final String DB_URL = "jdbc:mysql://localhost:3306/go_gin_test";
// MySQL 8.0 以上版本 - JDBC 驱动名及数据库 URL
/*
* final:修饰的类不能被继承。
* static:修饰符能够与变量、方法一起使用,表示是“静态”的
* */
// static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
// static final String DB_URL = "jdbc:mysql://127.0.0.1:3306/go_gin_test?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
// 日志方法
private static Logger logger = Logger.getLogger(day01jdbc.class);
// 配置文件封装方法
private static String LoadProperties(String jdbcPATH,String jdbcData) throws Exception {
Properties properties = new Properties(); // Properties该类主要用于读取Java的配置文件,
// FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等
InputStream iStream = new FileInputStream(new File(jdbcPATH));
properties.load(iStream); // 使用Properties对象里的方法读取FileInputStream返回的字节流
/*
* getProperty在此属性列表中搜索具有指定键的属性。如果在此属性列表中找不到该键,则会检查默认属性列表及其默认值(递归)。如果未找到该属性,则该方法返回默认值参数。
* */
// String key = properties.getProperty("jdbc.USER");
String key = properties.getProperty(jdbcData);
return key;
}
public static void main(String[] args) throws Exception { //ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
String DB_URL = LoadProperties("src/day07/jdbcmysql.properties","jdbc.DB_URL");
String USER = LoadProperties("src/day07/jdbcmysql.properties","jdbc.USER");
String PASS = LoadProperties("src/day07/jdbcmysql.properties","jdbc.PASS");
String JDBC_DRIVER = LoadProperties("src/day07/jdbcmysql.properties","jdbc.JDBC_DRIVER");
Connection conn = null;
Statement stmt = null;
try {
// 注册 JDBC 驱动
logger.info(Class.forName(JDBC_DRIVER));
// 打开链接
System.out.println("连接数据库...");
// DriverManager`提供的静态方法`getConnection()`自动扫描classpath,找到所有的JDBC驱动,然后根据我们传入的URL自动挑选一个合适的驱动。
conn = DriverManager.getConnection(DB_URL, USER, PASS);
logger.info(conn);
// 执行查询
System.out.println(" 实例化Statement对象...");
stmt = conn.createStatement();
logger.info(stmt);
String sql;
sql = "SELECT id, `name`, money FROM gin_user";
ResultSet rs = stmt.executeQuery(sql);
// 展开结果集数据库
while (rs.next()) { // next 返回第一个元素
// 通过字段检索
int id = rs.getInt("id");
String name = rs.getString("name");
String money = rs.getString("money");
// 输出数据
System.out.print("ID: " + id);
System.out.print(", NAME: " + name);
System.out.print(", money: " + money);
System.out.print("\n");
}
// 完成后关闭
rs.close();
stmt.close();
conn.close();
} catch (SQLException se) {
// 处理 JDBC 错误
logger.info(se);
se.printStackTrace();
} catch (Exception e) {
// 处理 Class.forName 错误
logger.info(e);
e.printStackTrace();
} finally {
// 关闭资源
try {
if (stmt != null) stmt.close();
} catch (SQLException se2) {
}// 什么都不做
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
```
**运行结果:**
```
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:54)----class com.mysql.cj.jdbc.Driver
连接数据库...
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:60)----com.mysql.cj.jdbc.ConnectionImpl@38082d64
实例化Statement对象...
[INFO] 2021-02-12 17:15:11 method: day07.day01jdbc.main(day01jdbc.java:65)----com.mysql.cj.jdbc.StatementImpl@5d624da6
ID: 1, NAME: WW, money: 23492
ID: 2, NAME: 风清扬, money: 23021
ID: 3, NAME: 洪七公, money: 18000
ID: 4, NAME: 降龙十八掌, money: 8000
ID: 5, NAME: 张无忌, money: 6000
ID: 6, NAME: 张三丰, money: 13000
ID: 7, NAME: 杨过, money: 9210
ID: 8, NAME: 小龙女, money: 5000
ID: 9, NAME: 小龙女, money: 5200
ID: 10, NAME: WW, money: 3210
ID: 11, NAME: 马可波罗, money: 10100
ID: 12, NAME: 令狐冲, money: 2340
ID: 13, NAME: 东方不败, money: 7800
ID: 14, NAME: 独孤求败, money: 12380
ID: 15, NAME: 剑圣, money: 29380
ID: 16, NAME: taotaomao, money: 3400
ID: 17, NAME: meimeixin, money: 5400
ID: 18, NAME: kexinle, money: 6800
ID: 19, NAME: HdfFFs, money: 3452
ID: 20, NAME: PdSSc, money: 23410
ID: 21, NAME: asjkhd, money: 23121
Goodbye!
```
<br>
<br>
## 数据类型
有的童鞋可能注意到了,使用JDBC的时候,我们需要在Java数据类型和SQL数据类型之间进行转换。JDBC在`java.sql.Types`定义了一组常量来表示如何映射SQL数据类型,但是平时我们使用的类型通常也就以下几种:
| SQL数据类型 | Java数据类型 |
| --- | --- |
| BIT, BOOL | boolean |
| INTEGER | int |
| BIGINT | long |
| REAL | float |
| FLOAT, DOUBLE | double |
| CHAR, VARCHAR | String |
| DECIMAL | BigDecimal |
| DATE | java.sql.Date, LocalDate |
| TIME | java.sql.Time, LocalTime |
注意:只有最新的JDBC驱动才支持`LocalDate`和`LocalTime`。
- Java自动化测试
- 第一章:Java:基础内容
- 1.1:Java:Hello Word
- 1.2:Java:热身
- 1.3:Java:注释
- 1.4:Java:标识符
- 1.5:Java:常量
- 1.6:Java:基本数据类型
- 1.7:Java:引用类型
- 1.8:Java:String类
- 第二章:Java:运算符
- 2.1:Java:算数运算符
- 2.2:Java:关系运算符
- 2.3:Java:逻辑运算
- 2.4:Java:赋值运算符
- 2.5;Java:三元运算符
- 2.6:Java:位运算符
- 第三章:Java:循环控制语句
- 3.1:Java:for循环
- 3.2:Java:while循环
- 3.3:Java:switch
- 3.4:Java:if else
- 3.5:Java:练习题
- 第四章:Java:函数与全局/局部变量
- 4.1:Java:局部变量
- 4.2:Java:全局变量
- 第五章:Java:方法
- 5.1:Java:初识方法
- 5.2:Java:方法调用
- 5.3:Java:方法重载
- 5.4:Java:构造方法
- 5.5:Java:方法的注意事项
- 第六章:Java:面向对象
- 6.1:Java:小案例
- 6.2:Java:this 关键字
- 6.3:Java:super 关键字
- 6.4:Java:static 关键字
- 6.5:Java:final关键字
- 6.6:Java:instanceof 运算符
- 6.7:Java:面向对象之封装
- 6.8:Java:面向对象之继承
- 6.9:Java:面向对象之多态
- 第七章:Java:面向对象高级进阶
- 7.1:Java:抽象类
- 7.2:Java:Java中String类
- 7.3:Java:interface接口
- 7.4:Java:ArrayList
- 7.5:Java:HashSet
- 7.6:Java:HashMap
- 7.7:Java:反射(reflection)
- 第八章:Java:日志以及异常捕获
- 8.1:Java:log4j
- 8.2:Java:异常初识基础
- 8.3:Java:未被捕获的异常
- 8.4:Java:try和catch的使用
- 8.5:Java:多重catch语句的使用
- 8.6:Java:throws/throw 关键字
- 8.7:Java:finally关键字
- 8.8:Java:自定义异常
- 第九章:Java:xml and IO
- 9.1:Java:IO基本概念
- 9.2:java:properties
- 9.3:Java:xml基本介绍
- 9.4:Java:xml操作实例
- 第十章:Java:JDBC编程
- 10.1:Java:JDBC介绍
- 10.2:Java:JDBC查询
- 10.3:Java:JDBC插入
- 10.4:Java:Batch
- 10.5:Java:JDBC连接池
- 第十一章:Java:TestNG
- 11.1:java:TestNG简介
- 11.2:Java:TestNG小实例
- 11.3:Java:TestNG.xml文件配置
- 11.4:Java:TestNG基本注解
- 11.5:Java:TestNG注解代码
- 11.6:Java:TestNG预期异常
- 11.7:Java:TestNG忽略测试
- 11.8:Java:TestNG超时测试
- 11.9:Java:TestNG分组测试