JDBC数据源接口
对于小型应用程序,可以使用JDBC数据库连接步骤示例中所示的DriveManager来获得连接,但是任何企业应用程序无疑都将使用DataSource作为连接数据源的方式。使用JDBC DataSource对象,我们可以获得连接池和分布式事务的优势,以及其他优势,例如配置时间DS等待连接,松散耦合,以便在将DB移动到其他服务器时,可以在以下位置更改服务器的属性数据源对象。
Java中的DataSource接口
javax.sql.DataSource接口是用于连接物理数据源的工厂。 DataSource接口由驱动程序供应商实现,共有三种类型的实现:
- 基本实现–此实现产生一个标准的Connection对象。通过基本实现,通过DataSource对象获得的连接与通过DriverManager类获得的连接相同。
- 连接池实现–在此实现中,有一个数据库连接对象的缓存,称为连接池。在运行时,应用程序从池中请求连接,而不是每次都创建新连接。
- 分布式事务实现–产生一个Connection对象,该对象可用于分布式事务(访问两个或者多个DBMS服务器的事务)。
JDBC驱动程序应至少包括基本的DataSource实现。例如,DataSource的Derby DB实现是org.apache.derby.jdbc.BasicClientDataSource40类,MySQL提供的实现是com.mysql.jdbc.jdbc2.optional.MysqlDataSource类,对于Oracle,它是oracle.jdbc.pool.OracleDataSource。
JDBC DataSource接口中的方法
- getConnection()–尝试与此DataSource对象表示的数据源建立连接。
- getConnection(String username,String password)–尝试通过传递凭据(例如用户名和密码)来与此DataSource对象表示的数据源建立连接。
- getLoginTimeout()–获取此数据源在尝试连接数据库时可以等待的最长时间(以秒为单位)。
- setLoginTimeout(int seconds)–设置此数据源在尝试连接数据库时将等待的最长时间(以秒为单位)。
JDBC数据源示例
我们来看一个使用MySQL DataSource的示例。使用的模式为theitroad,表为EMPLOYEE,其列为id,FIRST_NAME,LAST_NAME和DEPARTMENT。我们应该在类路径中包含mysql-connector jar。
从类路径中的属性文件db.properties中读取属性。
MYSQL.DRIVER_CLASS=com.mysql.cj.jdbc.Driver MYSQL.DB_URL=jdbc:mysql://localhost:3306/theitroad MYSQL.DB_USER=root MYSQL.DB_PASSWORD=admin
用于创建MysqlDataSource实例的类。
class MyDataSource {
public static DataSource getMySQLDS() {
MysqlDataSource mySqlDS = new MysqlDataSource();
MyDataSource myDS = new MyDataSource();
Properties properties = myDS.loadProperties();
mySqlDS.setUrl(properties.getProperty("MYSQL.DB_URL"));
mySqlDS.setUser(properties.getProperty("MYSQL.DB_USER"));
mySqlDS.setPassword(properties.getProperty("MYSQL.DB_PASSWORD"));
return mySqlDS;
}
// Method to load the properties file
private Properties loadProperties(){
Properties properties = new Properties();
InputStream inputStream = null;
try {
// Loading properties file from the classpath
inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("db.properties");
if(inputStream == null){
throw new IOException("File not found");
}
properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(inputStream != null){
inputStream.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return properties;
}
}
通过获取MySQLDataSource实例并使用该连接对象获取PreparedStatement实例来创建连接的类。
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import com.mysql.cj.jdbc.MysqlDataSource;
public class DSDemo {
public static void main(String[] args) {
DSDemo dsDemo = new DSDemo();
dsDemo.displayEmployeeById(16);
}
private void displayEmployeeById(int id){
Connection connection = null;
String selectSQL = "SELECT * FROM EMPLOYEE WHERE id = ?";
PreparedStatement prepStmt = null;
try {
DataSource ds = MyDataSource.getMySQLDS();
connection = ds.getConnection();
prepStmt = connection.prepareStatement(selectSQL);
prepStmt.setInt(1, id);
ResultSet rs = prepStmt.executeQuery();
while(rs.next()){
System.out.println("id: " + rs.getInt("id"));
System.out.println("First Name: " + rs.getString("FIRST_NAME"));
System.out.println("Last Name: " + rs.getString("LAST_NAME"));
System.out.println("Department: " + rs.getString("DEPARTMENT"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
由MySQL,Oracle等数据库供应商提供的这些基本DataSource实现具有将代码与特定数据库供应商紧密耦合的缺点。有第三方库,例如Apache DBCP,C3P0,可与任何数据库供应商一起使用,并提供可提高应用程序效率的池化数据源。

