JDBC筆記整理3(資料庫連線池與DRUID).md
1.)連線池原理
說明:以前使用的jdbc的缺點:
1、操作資料庫都需要建立連線,操作完成還需要關閉連線 2、建立連線和關閉連線需要可能比執行sql需要的時間都長 3、一個網站需要高頻繁的訪問資料庫,如果短時間頻繁的訪問資料庫伺服器, 就容易造成伺服器的宕機,即宕機。
資料庫連線池結構:
首先建立一定數量的連線,然後放到指定的地方。當我們需要獲取連線的時候,直接從指定的地方獲取。 用完了,我們再將連線放回去。這樣就能將我們連線的回收利用。並且不用花費大量時間在建立和銷燬連線上。
自定義連線池程式碼範例:
範例 表格:名稱:emp
id | name | city |
---|---|---|
1 | 劉備 | 北京 |
2 | 關羽 | 上海 |
3 | 張飛 | 廣州 |
需求:查詢emp表的所有使用者。
public class MyDatasourceTest {
//使用連線池實現
@Test
public void demo1() {
//1.從連線池獲取連線
//2.將用完的連線放回到連線池中
//建立自定義連線池物件,初始化連線池
MyDatasource ds = new MyDatasource();
// 初始化值
Connection conn = null;
ResultSet rs = null;
PreparedStatement pst = null;
try {
// 獲取連線// conn = JDBCUtils.getConnection();
conn=ds.getConnection();
String sql = "select * from emp";
// 獲取傳送sql的物件
pst = conn.prepareStatement(sql);
// 執行sql
rs = pst.executeQuery();
//處理結果
while(rs.next())
{
//取出資料
int id = rs.getInt("id");
String name = rs.getString("name");
String city = rs.getString("city" );
//輸出
System.out.println(id+"==="+name+"----"+city);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
JDBCUtils.release(null, pst, rs);
//2.將用完的連線放回到連線池中
ds.backPool(conn);
}
}
}
2.) 資料庫連線池的實現步驟:
1、建立自定義連線池類 實現 javax.sql.DataSource介面;這是sun公司規定。
2、建立儲存資料庫連線的集合類使用LinkedList。 當做連線池。
3、在自定義連線池類的建構函式中始化資料庫連線池,批量建立與資料庫的連線(Connection),把連線儲存到集合中。
4、實現DataSource這個介面中的getConnection()方法,每次呼叫getConnection方法時,從集合物件中取一個connection物件給使用者。
注意:這個方法是從我們資料庫連線池中獲取連線,從連線池中獲取之後需要將池子中的連線物件給刪掉。這樣就可以保證每次從連線池中獲取的連線都是唯一的,不會重複的。
5、使用完connection 連線,呼叫自定義的backPool方法,將connection連線放回集合中,不要交給資料庫。
注意:這裡只是將連線放回到連線池中,而不是關閉連線。
DRUID(阿里巴巴-德魯伊)連線池:
在工具類增加程式碼使用德魯伊獲取連線
具體程式碼如下:
3.) public static Connection getDruidConnection()
{
try {
//建立Properties集合物件
Properties p = new Properties();
//呼叫方法載入配置檔案中的資料
p.load(new FileInputStream("druid.properties"));
//使用德魯伊核心類呼叫靜態方法獲取配置檔案中的資料
DataSource ds = DruidDataSourceFactory.createDataSource(p);
//從德魯伊資料庫連線池中獲取連線
Connection conn = ds.getConnection();
//返回連線
return conn;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3.)JdbcTemplate概念
JDBC已經能夠滿足大部分使用者最基本的需求,但是在使用JDBC時,必須自己來管理資料庫資源。 JdbcTemplate就是Spring對JDBC的封裝,目的是使JDBC更加易於使用。JdbcTemplate是Spring的一部分。 JdbcTemplate處理了資源的建立和釋放。他幫助我們避免一些常見的錯誤,比如忘了總要關閉連線。 他執行核心的JDBC工作流,如PreparedStatement的建立和執行,而我們只需要提供SQL語句和提取結果。
JdbcTemplate中的方法
功能說明
execute() | 用於執行DDL語句,如:建表 瞭解 |
---|---|
update() | 用於執行DML語句,實現對資料庫表的增刪改操作 掌握 |
queryXxx() | 用於執行DQL語句,實現對資料庫表的各種查詢的操作 一定掌握 |
JdbcTemplate類的構造方法:
JdbcTemplate(DataSource dataSource) | Construct a new JdbcTemplate, given a DataSource to obtain connections from. |
---|
JdbcTemplate類的方法:
JdbcTemplate類中建立表的方法:DDL(建表)語句 | public void execute(String sql) | 執行建表語句,沒有返回值。引數是SQL語句,屬於String型別。 |
JdbcTemplate類中修改表的方法:DML(修改表)語句 | public int update(String sql, Object…args) | 執行DML語句,對資料庫表中的資料進行增刪改操作返回:影響的行數引數:1) sql語句2) args是用來替換佔位符的真實值,可變的引數 |
JdbcTemplate類中查詢表的方法:執行DQL(查表)語句 | query() | 通用的查詢方法,有多個同名方法的過載,可以自定義查詢結果集封裝成什麼樣的物件。 |
public <T> List<T> query(String sql, RowMapper<T> rowMapper) 執行查詢語句,返回一個List集合,List中存放的是RowMapper指定型別的資料。
說明: 1)query() 必須要指定查詢的結果集與JavaBean屬性之間的對應關係,而結果集與JavaBean屬性之間的對應關係需要傳遞一個介面作為query方法引數來確定。這個介面就是:RowMapper。 而RowMapper屬於介面,不能建立物件,我們使用其實現類BeanPropertyRowMapper來建立物件。 BeanPropertyRowMapper類如下所示: public class BeanPropertyRowMapper implements RowMapper 我們發現:BeanPropertyRowMapper類實現了RowMapper介面。所以我們只需要建立BeanPropertyRowMapper類的物件,然後將建立好的物件作為query方法的第二個引數傳遞即可。 2)BeanPropertyRowMapper類的構造方法說明:BeanPropertyRowMapper(Class mappedClass) 補充:mappedClass表示某個類的Class物件,這裡我們在使用的時候只需要在構造方法中給某個類的.class即可。 例如:Student.class。 只要我們給某個類的.class物件,在底層那麼就會將資料庫表中對應的欄位值給這個類的成員變數賦值, 所以在建立JavaBean的時候,要求成員變數名一定要和資料庫表中的欄位名一致,這樣才可以完成封裝。 使用舉例:
List<Student> students = jdbcTemplate.query("select * from student", new BeanPropertyRowMapper<>(Student.class));
queryForList() 返回多條記錄的查詢結果,封裝成一個List集合 預設List集合中的每個元素是Map物件,即List<Map<String,Object>> 如果要封裝成List物件,使用query()方法。
public List<Map<String, Object>> queryForList(String sql, Object... args) 傳入引數,執行查詢語句,返回一個List集合,List中存放的是Map型別的資料。
說明: 1)使用舉例: List<Map<String, Object>> mapList = jdbcTemplate.queryForList(“select * from student”); 2)多行多列。 queryForObject() 返回查詢只有單一物件的結果,這個單一結果應該是簡單的資料型別,如:Integer.class、Long.class、String.class, 不能直接封裝成JavaBean物件。可以用於聚合函式的查詢結果。
public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):傳入引數, 執行查詢語句,返回一個指定型別的資料。
說明: 1)返回查詢只有單一物件的結果,這個單一結果應該是簡單的資料型別,如:int.class、long.class、 String.class。也可以用於聚合函式的查詢結果。 2)引數: sql:表示要執行的sql語句. requiredType:表示必須給的型別,最後需要返回的Class類的物件. args:屬於可變引數,傳入的真實引數,例如給sql語句的佔位符賦值的真實值. 使用舉例: String name= jdbcTemplate.queryForObject(“select name from student where id=?”,String.class,2); 第一個引數表示一條sql語句 String.class表示查詢出來name列的型別的Class物件 2 表示id是2的資料 3)查詢的是單行單列。 queryForMap() 返回Map<String,Object>的查詢結果,其中鍵是列名,值是表中對應的記錄。 用於查詢結果只有1條記錄的情況。如果結果集返回多條記錄會出現異常。
public Map<String, Object> queryForMap(String sql, Object... args) 傳入引數,執行查詢語句,將一條記錄放到一個Map中。
說明: 1)引數: sql 表示查詢的sql語句 args 表示給第一個引數的sql語句的佔位符,設定值的 使用舉例: Map<String, Object> map = jdbcTemplate.queryForMap(“select * from student where id=?”, 2); 第一個引數表示一條sql語句 2 表示id是2的資料 2)查詢單行多列