1、數據庫連接池
概念
數據庫連接池是一個存放數據庫連接的容器。當系統初始化好後,容器被創建,容器中會申請一些連接對象,當用戶來訪問數據庫時,從容器中獲取連接對象,用戶訪問完之後,會將連接對象歸還給容器。
好處:節約資源、用戶訪問高效。
標準接口
javax.sql包下的DataSource
1、方法:
獲取連接:getConnection()
歸還連接:Connection.close()。如果連接對象是從連接池中獲取的,那麼調用Connection.close()方法,則不會再關閉連接,而是歸還連接。
2、數據庫連接池技術:C3P0、Druid
C3P0
1、步驟:
①導入兩個jar包:c3p0-0.9.5.2.jar和mchange-commons-java-0.2.12.jar,同時也需要導入數據庫驅動jar包。
②定義配置文件:c3p0.properties或c3p0-config.xml,直接放在src目錄下。
③創建核心對象:數據庫連接對象,ComboPooledDataSource
④獲取連接:getConnection
2、目錄結構
3、簡單實現
public class Demo { public static void main(String[] args) throws SQLException { //創建數據庫連接池對象 DataSource ds = new ComboPooledDataSource(); //獲取連接對象 Connection conn = ds.getConnection(); //打印 System.out.println(conn); } }
Druid:阿里巴巴提供
1、步驟:
①導入jar包:druid-1.0.9.jar
②定義配置文件:properties形式,可以叫任何名,可以放在任何目錄下。
③加載配置文件
④獲取數據庫連接池對象:通過工廠類來獲取,DruidDataSourceFactory
⑤獲取連接:getConnection
2、簡單實現
druid.properties(放在了src下)
driverClassName = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost:3306/db1?serverTimezone=GMT%2B8 username = root password = initialSize = 5 maxActive = 10 maxWait = 3000
DruidDemo.java
package druid; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; public class DruidDemo { public static void main(String[] args) { //1.導入jar包 //2.定義配置文件 //3.加載配置文件 Connection conn = null; try { Properties pro = new Properties(); ClassLoader classLoader = DruidDemo.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("druid.properties"); pro.load(is); //4.獲取連接池對象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); //5.獲取連接 conn = ds.getConnection(); System.out.println(conn); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
Druid例子,工具類實現數據庫添加操作
druid.properties
driverClassName = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost:3306/db1?serverTimezone=GMT%2B8 username = root password = initialSize = 5 maxActive = 10 maxWait = 3000
JDBCUtils.java
package utils; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.sql.DataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; /* * Druid連接池的工具類 */ public class JDBCUtils { //1.定義成員變量 private static DataSource ds; static { try { //1.加載配置文件 Properties pro = new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.獲取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } //獲取連接 public static Connection getConnection() throws SQLException { return ds.getConnection(); } //釋放資源 public static void close(Statement stmt, Connection conn) { if(stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); // 歸還連接 } catch (SQLException e) { e.printStackTrace(); } } } //釋放資源 public static void close(ResultSet rs, Statement stmt, Connection conn) { if(rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); // 歸還連接 } catch (SQLException e) { e.printStackTrace(); } } } //獲取連接池 public static DataSource getDataSource() { return ds; } }
DruidDemo.java
package druid; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import utils.JDBCUtils; public class DruidDemo { public static void main(String[] args) { //完成添加操作,給account表添加一條記錄 Connection conn = null; PreparedStatement pstmt = null; try { conn = JDBCUtils.getConnection(); String sql = "insert into account values(null, ?, ?)"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, "Mike"); pstmt.setDouble(2, 5000); int count = pstmt.executeUpdate(); System.out.println(count); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtils.close(pstmt, conn); } } }
2、JDBCTemplate
簡單說明
Spring框架對JDBC的簡單封裝,提供了一個JDBCTemplate對象簡化JDBC的開發。
步驟
1、導入jar包。
2、創建JdbcTemplate對象,依賴於數據源DataSource。
3、調用JdbcTemplate的方法來完成數據庫操作:
update():執行DML語句。
queryForMap():查詢結果,將結果集封裝爲map集合。
queryForList():查詢結果,將結果集封裝爲list集合。
query():查詢結果,將結果集封裝爲JavaBean對象。
queryForObject():查詢結果,將結果集封裝爲對象。
例子
druid.properties和JDBCUtils.java用的是上面那個例子的。
Demo.java
package jdbctemplate; import org.springframework.jdbc.core.JdbcTemplate; import utils.JDBCUtils; public class Demo { public static void main(String[] args) { //1.導入jar包 //2.創建JDBCTemplate對象 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //3.調用方法 String sql = "update account set money = 5000 where id = ?"; int count = template.update(sql, 1); System.out.println(count); } }
不需要我們再去手動申請連接和釋放連接了。
JDBCTemplate執行DML、DQL語句
Account.java
package jdbctemplate; public class Account { private int id; private String name; private double money; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "Account [id=" + id + ", name=" + name + ", money=" + money + "]"; } }
Demo.java
package jdbctemplate; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import utils.JDBCUtils; public class Demo { private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //1.將1號的money改爲8000 @Test public void test1() { String sql = "update account set money = 8000 where id = ?"; int count = template.update(sql, 1); System.out.println(count); } //2.添加一條記錄 @Test public void test2() { String sql = "insert into account values(?, ?, ?)"; int count = template.update(sql, 5, "Anny", 6000); System.out.println(count); } //3.刪除一條記錄 @Test public void test3() { String sql = "delete from account where id = ?"; int count = template.update(sql, 5); System.out.println(count); } //4.查詢id爲1的記錄,將其封裝成map集合 @Test public void test4() { String sql = "select * from account where id = ?"; Map<String, Object> mp = template.queryForMap(sql, 1); System.out.println(mp); } //5.查詢所有記錄,將其封裝爲List @Test public void test5() { String sql = "select * from account"; List<Map<String, Object>> list = template.queryForList(sql); for(Map<String, Object> mp : list) { System.out.println(mp); } } //6.查詢所有記錄,將其封裝爲Account對象的List集合 @Test public void test6() { String sql = "select * from account"; List<Account> list = template.query(sql, new RowMapper<Account>() { @Override public Account mapRow(ResultSet rs, int i) throws SQLException { Account ac = new Account(); ac.setId(rs.getInt("id")); ac.setName(rs.getString("name")); ac.setMoney(rs.getDouble("money")); return ac; } }); for(Account account : list) { System.out.println(account); } } //簡化操作 @Test public void test6_2() { String sql = "select * from account"; List<Account> list = template.query(sql, new BeanPropertyRowMapper<Account>(Account.class)); for(Account account : list) { System.out.println(account); } } //7.查詢總記錄數 @Test public void test7() { String sql = "select count(id) from account"; Integer sum = template.queryForObject(sql, Integer.class); System.out.println(sum); } }