1. 程式人生 > >spring對資料持久化的支援總結

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>