JDBC示例– MySQL,Oracle

时间:2020-02-23 14:35:18  来源:igfitidea点击:

欢迎使用JDBC示例。
Java数据库连接或者JDBC API在Java应用程序和关系数据库服务器之间提供了行业标准的和数据库独立的连接。
就像我们可以"编写一次并在任何地方运行"的Java程序一样,JDBC提供了从Java程序连接到关系数据库的框架。

JDBC示例

JDBC API用于完成以下任务:

  • 建立与关系数据库服务器(如Oracle,MySQL等)的连接。
    JDBCAPI不提供用于连接至MongoDB等NoSQL数据库的框架。

  • 将SQL查询发送到要在数据库服务器上执行的Connection。

  • 处理查询执行所返回的结果。

我们将研究JDBC MySQL示例和JDBC Oracle示例。
我们将从属性文件中读取数据库配置,以使我们的代码与数据库驱动程序松散耦合。

JDBC驱动程序

JDBC API由两部分组成-第一部分是应用程序程序员将使用的JDBC API。
第二部分是连接到数据库服务器的低级API。
JDBC API的第一部分是java.sql软件包中标准Java软件包的一部分。

对于第二部分,有四种不同类型的JDBC驱动程序:

  • JDBC-ODBC Bridge加上ODBC驱动程序(类型1):此驱动程序使用ODBC驱动程序连接到数据库服务器。
    我们应该在要连接数据库的计算机上安装ODBC驱动程序,这就是为什么该驱动程序几乎过时的原因,仅在其他选项不可用时才应使用。

  • 本机API部分支持Java技术的驱动程序(类型2):这种类型的驱动程序将JDBC类转换为RDBMS服务器的客户端API。
    我们应该在要建立数据库连接的计算机上安装数据库客户端API。
    由于另外依赖数据库客户端API驱动程序,因此也不推荐使用该驱动程序。

  • 用于数据库中间件的纯Java驱动程序(类型3):这种类型的驱动程序将JDBC调用发送到可以连接到不同类型的数据库的中间件服务器。
    我们应该安装一个中间件服务器来使用这种驱动程序。
    这增加了另外的网络呼叫并降低了性能。
    因此,这也不是广泛使用的JDBC驱动程序。

  • 直接到数据库的纯Java驱动程序(类型4):这是首选的驱动程序,因为它将JDBC调用转换为数据库服务器可以理解的网络协议。
    此解决方案在客户端不需要任何其他API,并且适合通过网络进行数据库连接。
    但是,对于此解决方案,我们应该使用数据库特定的驱动程序,例如Oracle为Oracle DB提供的OJDBC jar和MySQL数据库为MySQL Connector/J。

让我们创建一个简单的JDBC示例项目,看看JDBC API如何帮助我们编写松耦合的代码以实现数据库连接。

在开始执行jdbc示例之前,我们需要做一些准备工作以使数据库服务器中的一些数据可以查询。

安装数据库服务器不在本教程的讨论范围之内,因此我假设您已安装数据库服务器。

我们将编写程序以连接到数据库服务器,并运行简单的jdbc查询并处理结果。
为了说明如何在使用JDBC API连接数据库时实现松耦合,我将使用Oracle和MySQL数据库系统。

在SQL脚本下运行,以创建表并在表中插入一些虚拟值。

--mysql create table
create table Users(
id  int(3) primary key,
name varchar(20),
email varchar(20),
country varchar(20),
password varchar(20)
);

--oracle create table
create table Users(
id  number(3) primary key,
name varchar2(20),
email varchar2(20),
country varchar2(20),
password varchar2(20)
);
  
--insert rows
INSERT INTO Users (id, name, email, country, password) 
VALUES (1, 'hyman', '[email protected]', 'San Franceco', 'hyman123');
INSERT INTO Users (id, name, email, country, password) 
VALUES (4, 'David', '[email protected]', 'USA', 'david123');
INSERT INTO Users (id, name, email, country, password) 
VALUES	(5, 'Raman', '[email protected]', 'UK', 'raman123');
commit;

请注意,Oracle和MySQL数据库中的数据类型不同,这就是为什么我提供了两个不同的SQL DDL查询来创建Users表的原因。
但是,两个数据库都使用SQL语言进行确认,因此两个数据库表的插入查询都相同。

JDBC示例–数据库驱动程序

从项目镜像中可以看到,我在lib目录中同时具有MySQL(mysql-connector-java-5.0.5.jar)和Oracle(ojdbc6-11.2.0.1.0.jar)type-4驱动程序,并将其添加到项目构建路径。
确保根据数据库服务器安装版本使用正确版本的Java驱动程序。
通常,这些jar随安装程序一起提供,因此您可以在安装包中找到它们。
如果您有基于Maven的应用程序,则也可以使用以下依赖项。

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.0.5</version>
</dependency>

<!-- You need to install ojdbc6 jar manually to your maven repository -->
<dependency>
  <groupId>com.oracle</groupId>
  <artifactId>ojdbc6</artifactId>
  <version>11.2.0.1.0</version>
</dependency>

JDBC数据库配置属性文件

我们将从属性文件中读取数据库配置详细信息。
这将帮助我们轻松地从Oracle切换到MySQL数据库,反之亦然。
我们所需要做的就是更改属性详细信息。

#mysql DB properties
#DB_DRIVER_CLASS=com.mysql.jdbc.Driver
#DB_URL=jdbc:mysql://localhost:3306/UserDB
#DB_USERNAME=hyman
#DB_PASSWORD=hyman123

#Oracle DB Properties
DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
DB_URL=jdbc:oracle:thin:@localhost:1571:MyDBSID
DB_USERNAME=scott
DB_PASSWORD=tiger

使用JDBC API时,数据库配置是最重要的细节。
我们应该知道的第一件事是要使用的Driver类。
对于Oracle数据库,驱动程序类为" oracle.jdbc.driver.OracleDriver"。
对于MySQL数据库,驱动程序类为com.mysql.jdbc.Driver
您将在它们各自的驱动程序jar文件中找到这些驱动程序类。
这两个都实现JDBCjava.sql.Driver接口。

第二个重要部分是数据库连接URL字符串。
每个数据库驱动程序都有其自己的配置数据库URL的方式,但是它们都在连接URL中具有主机,端口和架构详细信息。

MySQL数据库连接字符串格式为jdbc:mysql://<HOST>:<PORT>/<SCHEMA>。

Oracle数据库连接字符串格式为jdbc:oracle:thin:@ &lt;HOST>:&lt;PORT>:&lt;SID>

其他重要的详细信息是用于连接到数据库服务器的数据库用户名和密码详细信息。

JDBC示例程序

让我们看一个简单的jdbc示例程序,以了解如何读取上述属性并创建数据库连接。

package com.theitroad.jdbc;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class DBConnection {

	public static Connection getConnection() {
		Properties props = new Properties();
		FileInputStream fis = null;
		Connection con = null;
		try {
			fis = new FileInputStream("db.properties");
			props.load(fis);

			//load the Driver Class
			Class.forName(props.getProperty("DB_DRIVER_CLASS"));

			//create the connection now
			con = DriverManager.getConnection(props.getProperty("DB_URL"),
					props.getProperty("DB_USERNAME"),
					props.getProperty("DB_PASSWORD"));
		} catch (IOException | ClassNotFoundException | SQLException e) {
			//TODO Auto-generated catch block
			e.printStackTrace();
		}
		return con;
	}
}

上面的jdbc示例程序确实很简单。
首先,我们从属性文件中读取数据库配置详细信息,然后加载JDBC驱动程序并使用DriverManager创建连接。
请注意,此代码仅使用Java JDBC API类,无法知道它连接到哪种类型的数据库。
这也是为接口方法编写代码的一个很好的例子。

注意的重要代码是对Class.forName()方法的调用,这是用于创建给定类的实例的Java Reflection方法。
您可能想知道为什么我们使用反射而不是" new"运算符来创建对象,以及为什么我们只是创建对象而不使用它。

第一个原因是使用反射来创建实例有助于我们编写松耦合的代码,而如果使用new运算符则无法实现。
在这种情况下,如果不进行相应的代码更改,就无法切换到其他数据库。

不使用对象的原因是因为我们对创建对象不感兴趣。
主要目的是将类加载到内存中,以便驱动程序类可以将自身注册到DriverManager。
如果研究一下Driver类的实现,您会发现它们在将自身注册到DriverManager的位置具有静态块。

oracle.jdbc.driver.OracleDriver.java片段:

static
{
  try
  {
    if (defaultDriver == null)
    {
      defaultDriver = new oracle.jdbc.OracleDriver();
      DriverManager.registerDriver(defaultDriver);
    }
	//some code omitted for clarity
	}
}

com.mysql.jdbc.Driver.java片段:

static
{
  try
  {
    DriverManager.registerDriver(new Driver());
  } catch (SQLException E) {
    throw new RuntimeException("Can't register driver!");
  }
}

这是一个很好的示例,其中我们通过使用反射API使代码松散耦合。
因此,基本上,我们正在使用Class.forName()方法调用进行以下操作。

Driver driver = new OracleDriver();
DriverManager.registerDriver(driver);

DriverManager.getConnection()方法使用已注册的JDBC驱动程序来创建数据库连接。
如果获取数据库连接有任何问题,此方法将抛出java.sql.SQLException

现在,让我们编写一个简单的jdbc示例测试程序,以使用数据库连接并运行简单的查询。

JDBC语句和ResultSet

这是一个简单的jdbc示例程序,我们其中使用JDBC连接对数据库执行SQL查询,然后处理结果集。

package com.theitroad.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBConnectionTest {
	
	private static final String QUERY = "select id,name,email,country,password from Users";

	public static void main(String[] args) {
				
		//using try-with-resources to avoid closing resources (boiler plate code)
		try(Connection con = DBConnection.getConnection();
				Statement stmt = con.createStatement();
				ResultSet rs = stmt.executeQuery(QUERY)) {	
			
			while(rs.next()){
				int id = rs.getInt("id");
				String name = rs.getString("name");
				String email = rs.getString("email");
				String country = rs.getString("country");
				String password = rs.getString("password");
				System.out.println(id + "," +name+ "," +email+ "," +country+ "," +password);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
	}

}

请注意,我们正在使用Java 7 try-with-resources功能来确保资源在我们离开try-catch块后立即关闭。

JDBC Connection,Statement和ResultSet是昂贵的资源,我们在使用完它们后应立即关闭它们。

Connection.createStatement()用于创建Statement对象,然后executeQuery()方法用于运行查询并获取结果集对象。

第一次调用ResultSetnext()方法时,将光标移到第一行,随后的调用将光标移到结果集中的下一行。
如果没有更多行,则返回false并退出while循环。
我们使用结果集" getXXX()"方法获取列的值,然后将其写入控制台。

当我们在jdbc示例测试程序上面运行时,我们得到以下输出。

1,hyman,[email protected],San Franceco,hyman123
4,David,[email protected],USA,david123
5,Raman,[email protected],UK,raman123

只需从db.properties文件中取消注释MySQL数据库配置属性,然后注释Oracle数据库配置详细信息即可切换到MySQL数据库。
由于Oracle和MySQL数据库"用户"表中的数据相同,因此您将获得相同的输出。