一、數(shù)據(jù)庫(kù)連接池
1.1 概念:其實(shí)就是一個(gè)容器(集合),存放數(shù)據(jù)庫(kù)連接的容器。當(dāng)系統(tǒng)初始化好后,容器被創(chuàng)建,容器中會(huì)申請(qǐng)一些連接對(duì)象,當(dāng)用戶(hù)來(lái)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí),從容器中獲取連接對(duì)象,用戶(hù)訪(fǎng)問(wèn)完之后,會(huì)將連接對(duì)象歸還給容器。
1.2 好處:
1. 節(jié)約資源
2. 用戶(hù)訪(fǎng)問(wèn)高效
1.3 實(shí)現(xiàn):
1.3.1 標(biāo)準(zhǔn)接口:javax.sql包下的DataSource? ?
方法:
獲取連接:getConnection()
歸還連接:Connection.close()。如果連接對(duì)象Connection是從連接池中獲取的,那么調(diào)用Connection.close()方法,則不會(huì)再關(guān)閉連接了。而是歸還連接
1.3.2 一般我們不去實(shí)現(xiàn)它,有數(shù)據(jù)庫(kù)廠(chǎng)商來(lái)實(shí)現(xiàn)
C3P0:數(shù)據(jù)庫(kù)連接池技術(shù)
Druid:數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn)技術(shù),由阿里巴巴提供的
1.4 C3P0:數(shù)據(jù)庫(kù)連接池技術(shù)
1.4.1 步驟:
1. 導(dǎo)入jar包 (兩個(gè)) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
注意:不要忘記導(dǎo)入數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar包
2. 定義配置文件:
名稱(chēng): c3p0.properties 或者 c3p0-config.xml
路徑:直接將文件放在src目錄下即可。
3. 創(chuàng)建核心對(duì)象: 數(shù)據(jù)庫(kù)連接池對(duì)象 ComboPooledDataSource
4. 獲取連接: getConnection
1.4.2 代碼:
//1.創(chuàng)建數(shù)據(jù)庫(kù)連接池對(duì)象
DataSource ds??= new ComboPooledDataSource();
//2. 獲取連接對(duì)象
Connection conn = ds.getConnection();
1.5 Druid:數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn)技術(shù),由阿里巴巴提供的
1.5.1 步驟:
1. 導(dǎo)入jar包 druid-1.0.9.jar
2. 定義配置文件:是properties形式的,可以叫任意名稱(chēng),可以放在任意目錄下
3. 加載配置文件。Properties
4. 獲取數(shù)據(jù)庫(kù)連接池對(duì)象:通過(guò)工廠(chǎng)來(lái)來(lái)獲取??DruidDataSourceFactory
5. 獲取連接:getConnection
1.5.2 代碼:
//3.加載配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//4.獲取連接池對(duì)象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5.獲取連接
Connection conn = ds.getConnection();
1.6 定義工具類(lèi)
1. 定義一個(gè)類(lèi) JDBCUtils
2. 提供靜態(tài)代碼塊加載配置文件,初始化連接池對(duì)象
3. 提供方法
獲取連接方法:通過(guò)數(shù)據(jù)庫(kù)連接池獲取連接
釋放資源
獲取連接池的方法
代碼:
????????????public class JDBCUtils {
????????????????//1.定義成員變量 DataSource
????????????????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(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;
????????????????}
????????????}
二、Spring JDBC
2.1 Spring框架對(duì)JDBC的簡(jiǎn)單封裝。提供了一個(gè)JDBCTemplate對(duì)象簡(jiǎn)化JDBC的開(kāi)發(fā)
2.2 步驟:
1. 導(dǎo)入jar包
2. 創(chuàng)建JdbcTemplate對(duì)象。依賴(lài)于數(shù)據(jù)源DataSource
JdbcTemplate template = new JdbcTemplate(ds);
3. 調(diào)用JdbcTemplate的方法來(lái)完成CRUD的操作
update():執(zhí)行DML語(yǔ)句。增、刪、改語(yǔ)句
queryForMap():查詢(xún)結(jié)果將結(jié)果集封裝為map集合,將列名作為key,將值作為value 將這條記錄封裝為一個(gè)map集合
注意:這個(gè)方法查詢(xún)的結(jié)果集長(zhǎng)度只能是1
queryForList():查詢(xún)結(jié)果將結(jié)果集封裝為list集合
注意:將每一條記錄封裝為一個(gè)Map集合,再將Map集合裝載到List集合中
query():查詢(xún)結(jié)果,將結(jié)果封裝為JavaBean對(duì)象
query的參數(shù):RowMapper
一般我們使用BeanPropertyRowMapper實(shí)現(xiàn)類(lèi)。可以完成數(shù)據(jù)到JavaBean的自動(dòng)封裝
new BeanPropertyRowMapper<類(lèi)型>(類(lèi)型.class)
queryForObject:查詢(xún)結(jié)果,將結(jié)果封裝為對(duì)象
一般用于聚合函數(shù)的查詢(xún)
2.3 練習(xí):
2.3.1 需求:
1. 修改1號(hào)數(shù)據(jù)的 salary 為 10000
2. 添加一條記錄
3. 刪除剛才添加的記錄
4. 查詢(xún)id為1的記錄,將其封裝為Map集合
5. 查詢(xún)所有記錄,將其封裝為L(zhǎng)ist
6. 查詢(xún)所有記錄,將其封裝為Emp對(duì)象的List集合
7. 查詢(xún)總記錄數(shù)
2.3.2 代碼:
????????????????import cn.itcast.domain.Emp;
????????????????import cn.itcast.utils.JDBCUtils;
????????????????import org.junit.Test;
????????????????import org.springframework.jdbc.core.BeanPropertyRowMapper;
????????????????import org.springframework.jdbc.core.JdbcTemplate;
????????????????import org.springframework.jdbc.core.RowMapper;
????????????????import java.sql.Date;
????????????????import java.sql.ResultSet;
????????????????import java.sql.SQLException;
????????????????import java.util.List;
????????????????import java.util.Map;
public class JdbcTemplateDemo2 {
//Junit單元測(cè)試,可以讓方法獨(dú)立執(zhí)行
//1. 獲取JDBCTemplate對(duì)象
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
/**
* 1. 修改1號(hào)數(shù)據(jù)的 salary 為 10000
*/
@Test
public void test1(){
? ? ? ? ?//2. 定義sql
? ? ? ? ?String sql = "update emp set salary = 10000 where id = 1001";
? ? ? ? ?//3. 執(zhí)行sql
? ? ? ? ?int count = template.update(sql);
? ? ? ? ?System.out.println(count);
}
/**
* 2. 添加一條記錄
*/
@Test
public void test2(){
? ? ? ? ? ? ? ? String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
? ? ? ? ? ? ? ? int count = template.update(sql, 1015, "郭靖", 10);
? ? ? ? ? ? ? ? System.out.println(count);
}
/**
* 3.刪除剛才添加的記錄
*/
@Test
public void test3(){
? ? ? ? ? ? ? ?String sql = "delete from emp where id = ?";
? ? ? ? ? ? ? ?int count = template.update(sql, 1015);
? ? ? ? ? ? ? ?System.out.println(count);
}
/**
* 4.查詢(xún)id為1001的記錄,將其封裝為Map集合
* 注意:這個(gè)方法查詢(xún)的結(jié)果集長(zhǎng)度只能是1
*/
@Test
public void test4(){
? ? ? ? ? ? ? ? ? String sql = "select * from emp where id = ? or id = ?";
? ? ? ? ? ? ? ? ? Map<String, Object> map = template.queryForMap(sql, 1001,1002);
? ? ? ? ? ? ? ? ? System.out.println(map);
}
/**
* 5. 查詢(xún)所有記錄,將其封裝為L(zhǎng)ist
*/
@Test
public void test5(){
? ? ? ? ? ? ? ? ?String sql = "select * from emp";
? ? ? ? ? ? ? ? ?List<Map<String, Object>> list = template.queryForList(sql);
?? ??? ??? ?? ? ?for (Map<String, Object> stringObjectMap : list) {
????????????????????????????System.out.println(stringObjectMap);
? ? ? ? ? ? ? ? ?}
}
/**
* 6. 查詢(xún)所有記錄,將其封裝為Emp對(duì)象的List集合
*/
@Test
public void test6(){
? ? ? ? ? ? ? ? String sql = "select * from emp";
? ? ? ? ? ? ? ? List<Emp> list = template.query(sql, new RowMapper<Emp>() {
? ? ? ? ? ? ? ? ?@Override
? ? ? ? ? ? ? ? ?public Emp mapRow(ResultSet rs, int i) throws SQLException {
????????????????????????????????Emp emp = new Emp();
????????????????????????????????int id = rs.getInt("id");
????????????????????????????????String ename = rs.getString("ename");
????????????????????????????????int job_id = rs.getInt("job_id");
????????????????????????????????int mgr = rs.getInt("mgr");
????????????????????????????????Date joindate = rs.getDate("joindate");
????????????????????????????????double salary = rs.getDouble("salary");
????????????????????????????????double bonus = rs.getDouble("bonus");
????????????????????????????????int dept_id = rs.getInt("dept_id");
????????????????????????????????emp.setId(id);
????????????????????????????????emp.setEname(ename);
????????????????????????????????emp.setJob_id(job_id);
????????????????????????????????emp.setMgr(mgr);
????????????????????????????????emp.setJoindate(joindate);
????????????????????????????????emp.setSalary(salary);
????????????????????????????????emp.setBonus(bonus);
????????????????????????????????emp.setDept_id(dept_id);
????????????????????????????????return emp;
? ? ? ? ? ? ? ? ? ? ? ? ? }
?? ??? ??? ??? ?});
?? ??? ??? ??? ??for (Emp emp : list) {
????????????????????????????System.out.println(emp);
????????????????????????}
}
/**
* 6. 查詢(xún)所有記錄,將其封裝為Emp對(duì)象的List集合
*/
@Test
public void test6_2(){
? ? ? ? ? ? ? ? ? ?String sql = "select * from emp";
? ? ? ? ? ? ? ? ? ?List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
????????????????????????for (Emp emp : list) {
????????????????????????????System.out.println(emp);
????????????????????????}
}
/**
* 7. 查詢(xún)總記錄數(shù)
*/
? @Test
public void test7(){
? ? ? ? ? ? ? ? ? ?String sql = "select count(id) from emp";
? ? ? ? ? ? ? ? ? ?Long total = template.queryForObject(sql, Long.class);
? ? ? ? ? ? ? ? ? ?System.out.println(total);
}