spring對資料持久化的支援總結
1. JdbcTemplate
1.1. 優勢
1.1.1. 可以直接根據業務需求拼寫sql,以及sql語句需要的引數,從而直接獲取資料
1.1.2. 支援資料庫分割槽
1.2. 劣勢:sql語句直接寫在java程式中,後期難以管理
2. Spring+JdbcTemplate框架整合的步驟
2.1. 新增jar包
2.2. 根據資料表編寫實體類
2.3. 設計業務介面
2.4. 編寫介面實現類
2.4.1. 將JdbcTemplate作為EmpDaoImpl的屬性,並封裝getter,setter方法
2.4.2. 呼叫JdbcTemplate.update(String sql,Object[] param);
2.5. 建立jdbc.properties,以鍵值對方式儲存資料庫連線的資源資訊
2.6. 配置spring-common.xml
2.6.1. 注入PropertyPlaceholderConfigurer物件,載入jdbc.properties
2.6.2. 注入C3P0資料來源框架ComboPooledDataSource物件,為JdbcTemplate提供資料庫配置資訊以及Connection的連線池技術
2.6.3. 注入JdbcTemplate物件,實現資料庫增刪改查
2.6.4. 注入EmpDaoImpl物件,將之前配置完畢JdbcTemplate物件自動裝配
3. JdbcTemplate資料庫操作
3.1. 增刪改操作
int update(String sql,Object[] param);
3.2. 查詢
3.2.1. 獲取多行多列的資料:List<T> JdbcTemplate.query(String sql,Object[] param,RowMapper<T>)
3.2.2. 根據sql語句查詢的結果,在介面實現類中定義內部類,統一處理資料表每一行的列值與實體類的屬性的對應關係
// 定義內部類:統一處理獲取的表資料與Emp類屬性的對應關係
private class MyRowMapper implements RowMapper<Emp> {
@Override
public Emp mapRow(ResultSet rs, int rowNum) throws SQLException {
System.out.println("行號:" + rowNum);
Dept dept=new Dept();
dept.setDeptid(rs.getInt(7));
Emp emp = new Emp(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getDate(4), rs.getDouble(5),
rs.getDouble(6), dept);
return emp;
}
}
3.2.3. 獲取單行多列的資料
Emp emp= jdbcTemplate.query(sql, new Object[]{id}, new ResultSetExtractor<Emp>() {
@Override
public Emp extractData(ResultSet rs) throws SQLException, DataAccessException {
Emp emp=null;
Dept dept=null;
if (rs.next()) {
emp = new Emp();
emp.setEname(rs.getString("ename"));
emp.setHiredate(rs.getDate("hiredate"));
dept=new Dept();
dept.setDname(rs.getString("dname"));
emp.setDept(dept);
}
return emp;
}
});
3.2.4. 獲取聚合查詢的結果:使用分組或資料庫函式的查詢結果,例如統計每個部門的員工人數
需要在程式中定義幫助類,類的屬性要與查詢結果的所有列值對應
public class DeptUtil {
private String dname;
private Integer personNums;
}
String sql="SELECT d.dname,COUNT(1) as c from emp e "
+"LEFT JOIN dept d ON e.deptid=d.deptid "
+"GROUP BY d.dname";
List<DeptUtil> dus= jdbcTemplate.query(sql, new RowMapper<DeptUtil>(){
@Override
public DeptUtil mapRow(ResultSet rs, int rowNum) throws SQLException {
DeptUtil du=new DeptUtil(rs.getString("dname"), rs.getInt("c"));
return du;
}
});
3.2.5. 獲取單行單列的資料,例如統計所有員工的人數
String sql="select count(1) from emp";
int i=jdbcTemplate.queryForObject(sql, new RowMapper<Integer>(){
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
int i= rs.getInt(1);
return i;
}
});
4. Spring事務
4.1. 資料庫的事務: 事務是一組操作的執行單元,事務管理的是一組SQL指令,比如增加,修改,刪除等
4.2. 事務一致性:事務內的所有操作必須全部成功,或者全部失敗,不允許有部分成功的操作,否則導致業務操作不一致
4.3. 事務的四大特性
4.3.1. atomic(原子性):要麼都發生,要麼都不發生。
4.3.2. consistent(一致性):資料應該不被破壞。
4.3.3. isolate(隔離性):使用者間操作不相混淆
4.3.4. durable(永續性):永久儲存,例如儲存到資料庫中等
4.4. Spring的兩種事務管理方式
4.4.1. 程式設計式事務:編寫程式碼控制事務的回滾,比較繁瑣
4.4.2. 宣告式事務:通過xml檔案配置或者註解的方式實現根據業務的需要,為指定範圍的方法提供各種型別的事務
4.5. Spring控制事物的方式:spring控制事物是以bean元件的函式為單位的,如果一個函式正常執行完畢,該函式內的全部資料庫操作按照一次事物提交,如果丟擲異常,全部回滾
4.6. Spring事務處理的方法
4.7. 使用註解實現spring事務
//@Transactional 寫在需要提供事務的方法上
//readOnly 是否設定為只讀事務,為查詢操作提供事務,
//如果當前進行增刪改操作,建議設定readOnly=false
//propagation 設定事務傳播行為
//Propagation.REQUIRED 單例模式的事務,如果之前存在事務物件,則該方法使用之前//的事務,如果之前沒有事務物件,則spring提供一個新的事務物件
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
Spring配置檔案需要開啟註解功能
<!-- 開啟註解實現事務管理的功能,並指定之前配置的事務管理器的id-->
<tx:annotation-driven transaction-manager="tx" />
<!-- 開啟註解功能:讓所有寫有的註解的類生效 -->
<context:component-scan base-package="com"></context:component-scan>