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,可与任何数据库供应商一起使用,并提供可提高应用程序效率的池化数据源。