數據源有2種:
- 普通數據源 即數據庫驅動自帶的數據源
- 連接池 包括數據庫驅動自帶的連接池,以及DBCP、C3P0等常用的第三方連接池。
數據庫驅動自帶的數據源
1 //從properties文件加載數據源配置 2 Properties properties = new Properties(); 3 InputStream is = Class.forName("test.Test").getResourceAsStream("/mysqlDataSource.properties"); 4 properties.load(is); 5 String url=properties.getProperty("url"); 6 String user = properties.getProperty("user"); 7 String password = properties.getProperty("password"); 8 9 //設置普通數據源,因為使用的是MysqlDataSource類,驅動自然只能是mysql的驅動,這個類已經把數據庫驅動設置好了,不用我們設置。 10 MysqlDataSource mysqlDataSource = new MysqlDataSource(); 11 mysqlDataSource.setUrl(url); //還有個方法setURL(),這2個方法完全一樣,因為setURL()的函數體就是調用setUrl() 12 mysqlDataSource.setUser(user); 13 mysqlDataSource.setPassword(password); 14 15 //獲取連接,操作數據庫 16 Connection connection = mysqlDataSource.getConnection(); 17 String sql = "insert into student_tb (name,age,score) values (?,?,?)"; 18 PreparedStatement preparedStatement = connection.prepareStatement(sql); 19 preparedStatement.setString(1,"chy"); 20 preparedStatement.setInt(2,20); 21 preparedStatement.setInt(3,100); 22 preparedStatement.executeUpdate(); 23 preparedStatement.close(); 24 connection.close();
我導入的是Mysql的數據庫驅動,mysql驅動提供的自然是mysql數據源,已經默認注冊了mysql數據庫驅動,我們不必手動注冊。如果導入的其他數據庫的驅動,提供的自然就是該種數據庫的數據源。
一般來說,數據庫驅動都會提供2種數據源:普通數據源、連接池。
mysql驅動提供的普通數據源是MysqlDataSource,連接池是MysqlConnectionPoolDataSource,看名字就知道是連接池數據源。
數據庫驅動自帶的連接池
1 //從properties文件加載數據源配置 2 Properties properties = new Properties(); 3 InputStream is = Class.forName("test.Test").getResourceAsStream("/mysqlDataSource.properties"); 4 properties.load(is); 5 String url=properties.getProperty("url"); 6 String user = properties.getProperty("user"); 7 String password = properties.getProperty("password"); 8 9 //設置連接池 10 MysqlConnectionPoolDataSource poolDataSource = new MysqlConnectionPoolDataSource(); 11 poolDataSource.setURL(url); 12 poolDataSource.setUser(user); 13 poolDataSource.setPassword(password); 14 15 //獲取連接,操作數據庫 16 Connection connection = poolDataSource.getConnection(); 17 String sql = "insert into student_tb (name,age,score) values (?,?,?)"; 18 PreparedStatement ps = connection.prepareStatement(sql); 19 ps.setString(1,"chy"); 20 ps.setInt(2,20); 21 ps.setInt(3,99); 22 ps.executeUpdate(); 23 connection.close();
普通數據源采用直連數據庫的方式,調用 getConnection() 獲取連接時,實際上底層仍是調用 DriverManager.getConnection(url, user, password); 來獲取連接;關閉連接時,就是實實在在地關閉連接,釋放資源。
連接池是在服務器上創建一個連接池,預先建立一些數據庫連接,放在連接池中,調用 getConnection() 獲取連接時,只是從連接池中取出一個連接,調用close()關閉連接時,並不是真的關閉連接,是由連接池回收連接,下次還可以接着用。創建數據庫連接是很花時間的,使用連接池減少了時間開銷。
數據源適合需要多次創建數據庫連接的應用,如果不使用數據源,一個一個地DriverManager.getConnection(url, user, password);傳入url、user、password創建連接,很麻煩。
連接池數據源適合需要創建多個連接的應用。
DBCP數據源
DBCP是Apache的一個開源項目,Tomcat的連接池就是使用DBCP來實現的。
使用DBCP需要2個jar包:
- commons-dbcp2.jar dbcp的核心包,下載壓縮包后里面有
- commons-pool2.jar dbcp的依賴,需要單獨去下載
這2個都是在apache上下載,下載的時候要注意對應我們的JDK版本(實際上是對應JDK中JDBC的版本)。
此外,還需要2個額外的jar包:
- commons-logging.jar 日志包
- 數據庫驅動
DBCP常用的數據源類是BasicDataSource。
1 //從properties文件加載數據源配置 2 Properties properties = new Properties(); 3 InputStream is = Class.forName("test.Test").getResourceAsStream("/dataSource.properties"); 4 properties.load(is); 5 String driverStr = properties.getProperty("driver"); 6 String url=properties.getProperty("url"); 7 String username = properties.getProperty("username"); 8 String password = properties.getProperty("password"); 9 10 //設置連接池 11 BasicDataSource dataSource = new BasicDataSource(); 12 //這些第三方的數據源不知道我們使用的是何種數據庫,所以要手動設置數據庫驅動 13 dataSource.setDriverClassName(driverStr); //注意是setDriverClassName(),參數才是String 14 /* 15 也可以這樣寫: 16 java.sql.Driver driver = DriverManager.getDriver(driverStr); 17 dataSource.setDriver(driver); //參數是java.sql.Driver 18 Driver類在多個包下都有,注意不要寫錯了。 19 建議使用前一種,更簡單,不容易出錯。 20 */ 21 dataSource.setUrl(url); 22 dataSource.setUsername(username); //注意是setUsername(),不是setUser() 23 dataSource.setPassword(password); 24 25 //從數據源獲取連接獲取連接,操作數據庫 26 Connection connection = dataSource.getConnection(); 27 String sql = "insert into student_tb (name,age,score) values (?,?,?)"; 28 PreparedStatement ps = connection.prepareStatement(sql); 29 ps.setString(1,"chy"); 30 ps.setInt(2,20); 31 ps.setInt(3,99); 32 ps.executeUpdate(); 33 connection.close();
可以通過工廠來創建數據源:
BasicDataSource dataSource= BasicDataSourceFactory.createDataSource(properties); //參數是Properties類型
十分簡便,但對properties中的key有嚴格要求,比如說:
setUsername() => 去掉set,后面部分變為camel寫法,username。
如果key寫錯了,比如寫成了user,會報錯: Access denied for user ''@'localhost' (using password: YES) ,有時候報的是NO。
可以給數據源設置一些其他參數,比如:
dataSource.setInitialSize(5); //設置初始連接數,初始化連接池時會創建5個連接,放到連接池中 dataSource.setMinIdle(2); //設置最小空閑連接數,連接池中至少有2個連接是空閑的。idle,閑置的、無所事事。 dataSource.setMaxTotal(20); //設置最大連接數,連接池中最多可以有20個連接 //......
使用properties文件直接配置DBCP數據源
driver=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/my_db?serverTimezone=GMT username=chy password=abcd minIdle=2 maxIdle=10 initialSize=15 maxTotal=30
1 //從properties文件加載數據源配置 2 Properties properties = new Properties(); 3 InputStream is = Class.forName("test.Test").getResourceAsStream("/dataSource.properties"); 4 properties.load(is); 5 6 //設置連接池 7 BasicDataSource dataSource= BasicDataSourceFactory.createDataSource(properties); 8 9 //從數據源獲取連接獲取連接,操作數據庫 10 Connection connection = dataSource.getConnection(); 11 String sql = "insert into student_tb (name,age,score) values (?,?,?)"; 12 PreparedStatement ps = connection.prepareStatement(sql); 13 ps.setString(1,"chy"); 14 ps.setInt(2,20); 15 ps.setInt(3,99); 16 ps.executeUpdate(); 17 connection.close();
數據庫驅動自帶的數據源、c3p0直接使用properties文件配置,很容易出錯,不推薦。
dbcp可以直接使用properties文件配置,不容易出錯。
C3P0數據源
C3P0是mchange的開源項目,相比於DBCP,C3P0有自動回收閑置連接的功能,性能更優。
下載,解壓后lib文件夾下有3個jar包,把c3p0.jar、mchange-commons-java.jar這2個jar包添加到項目中,帶oracle的那個是Oracel才用的。
把數據庫驅動添加到項目中。
DBCP是Apache的,要添加自家的日志包commons-logging.jar,C3P0則不必添加日志包。
C3P0常用的數據源類是ComboPooledDataSource。
1 //從properties文件加載數據源配置 2 Properties properties = new Properties(); 3 InputStream is = Class.forName("test.Test2").getResourceAsStream("/dataSource.properties"); 4 properties.load(is); 5 String driver = properties.getProperty("driver"); 6 String jdbcUrl=properties.getProperty("jdbcUrl"); 7 String user = properties.getProperty("user"); 8 String password = properties.getProperty("password"); 9 10 //配置數據源 11 ComboPooledDataSource dataSource = new ComboPooledDataSource(); 12 dataSource.setDriverClass(driver); //只有這個方法,沒有setDriver() 13 dataSource.setJdbcUrl(jdbcUrl); //注意是setJdbcUrl(),和其他數據源不同 14 dataSource.setUser(user); 15 dataSource.setPassword(password); 16 17 //從數據源獲取連接,操作數據庫 18 Connection connection = dataSource.getConnection(); 19 String sql = "insert into student_tb (name,age,score) values (?,?,?)"; 20 PreparedStatement ps = connection.prepareStatement(sql); 21 ps.setString(1,"chy"); 22 ps.setInt(2,20); 23 ps.setInt(3,99); 24 ps.executeUpdate(); 25 connection.close();
相比於DBCP,C3P0可以設置更多的配置參數,比如:
dataSource.setMaxStatements(10);
dataSource.setMaxStatementsPerConnection(10);
這些配置一般不寫死在程序中,而是寫在配置文件中,從配置文件中加載配置。
DBCP不具備自動回收空閑連接的功能,C3P0具備。