Spring框架——JDBC
阿新 • • 發佈:2020-08-28
Spring與JDBC
資料庫配置
在beans.xml配置jdbc資料庫
<!-- 資料來源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName"> <value>com.mysql.jdbc.Driver</value> </property> <property name="url"> <value>jdbc:mysql://localhost:3306/mytest_db</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value></value> </property> </bean>
JdbcTemplate
類
功能
JdbcTemplate
類是Spring對JDBC支援類庫中的核心類
- 建立和釋放資源
- 執行SQL語句、儲存過程,並通過ResultSet來返回資料
在beans.xml配置
將dataSource依賴注入jdbcTemplate,指定執行操作的資料庫
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource"></property> </bean>
用法
- 增刪改
this.jdbcTemplate.update("insert into book(title,price) values(?,?)", book.getTitle(),book.getPrice());
- 返回自增值的增刪改
final String sql = "insert into book(title,price) values(?,?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); this.jdbcTemplate.update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement pstm = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); pstm.setString(1, book.getTitle()); pstm.setInt(2, book.getPrice()); return pstm; } }, keyHolder); int key = keyHolder.getKey().intValue(); System.out.println(key);
- 批處理
final String sql = "delete from book where id = ?";
this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstm, int index) throws SQLException {
pstm.setInt(1, ids[index]);
}
@Override
public int getBatchSize() {
return ids.length;
}
});
- 查詢
在Dao類中使用
@Repository
允許元件掃描來發現和配置自定義DAO
在類中配置該註解表示資料持久層
@Resource
持久化源,資料來源DataSource
依賴注入,獲取JdbcTemplate
@Repository
public class BookDaoImpl {
@Resource
private JdbcTemplate jdbcTemplate;
public List<String> find(){
return this.jdbcTemplate.queryForList("select name from menu", String.class);
}
public List<Menu> findAll(){
return this.jdbcTemplate.query("select * from menu", new RowMapper<Menu>() {
public Menu mapRow(ResultSet rs, int rowNum) throws SQLException{
Menu m = new Menu();
m.setId(rs.getInt(1));
m.setName(rs.getString(2));
m.setParentId(rs.getInt(3));
return m;
}
});
}
public Menu findById(int id) {
return this.jdbcTemplate.queryForObject("select * from menu where id = ?",
new Object[] {id},
new RowMapper<Menu>() {
public Menu mapRow(ResultSet rs, int rowNum) throws SQLException{
Menu m = new Menu();
m.setId(rs.getInt(1));
m.setName(rs.getString(2));
m.setParentId(rs.getInt(3));
return m;
}
});
}
public int countParentIdNull() {
int count = this.jdbcTemplate.queryForObject("select count(id) from menu where parentId is not null", Integer.class);
return count;
}
public void saveBook(Book book) {
this.jdbcTemplate.update("insert into book(title,price) values(?,?)",
book.getTitle(), book.getPrice());
final String sql = "insert into book(title,price) values(?,?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
this.jdbcTemplate.update(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement pstm = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstm.setString(1, book.getTitle());
pstm.setInt(2, book.getPrice());
return pstm;
}
}, keyHolder);
int key = keyHolder.getKey().intValue();
System.out.println(key);
}
public void batchDelete(int[] ids) {
final String sql = "delete from book where id = ?";
this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement pstm, int index) throws SQLException {
pstm.setInt(1, ids[index]);
}
@Override
public int getBatchSize() {
return ids.length;
}
});
}
}
在Service類中
@Service
在類中配置該註解表示業務邏輯層
@Resource
依賴注入,將Dao依賴注入進Service,獲取Dao
@Service
public class BookServiceImpl {
@Resource
private BookDaoImpl bookDaoImpl;
public void addBook(Book book) {
this.bookDaoImpl.saveBook(book);
}
public void batchDelete(int[] ids) {
this.bookDaoImpl.batchDelete(ids);
}
public int count() {
return this.bookDaoImpl.countParentIdNull();
}
public Menu findById(int id) {
return this.bookDaoImpl.findById(id);
}
public List<Menu> findAll(){
return this.bookDaoImpl.findAll();
}
public List<String> find(){
return this.bookDaoImpl.find();
}
}
Spring與事務
概念
事務是一組原子操作的工作單元
-
原子性(Atomic)
事務由一個或多個行為捆綁在一起組成一個單獨的工作單元,原子性保證事務中的所有操作要麼都發生,要麼都不發生
-
一致性(Consistent)
一旦一個事務結束了(不管成功與否),系統所處的狀態和它的業務規則是一致的,也就是說資料應當不會被破壞
-
隔離性(Isolated)
事務應該允許多名使用者操作同一個資料,一名使用者的操作不會和其他使用者的操作相混淆(隔離級別)
-
永續性(Durable)
一旦事務完成,事務的結果應該持久化,用來保證即使系統崩潰也不會破壞事務的結果
Spring框架提供了程式設計式事務管理和宣告式事務管理
程式設計式事務
- 可以清楚地控制事務的邊界
- 可自行實現事務開始時間、結束時間、撤消操作的時機等
- 可以實現細粒度的事務控制
beans.xml
<!-- 事務 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
宣告式事務
- 事務管理的API不介入程式,最符合一個非侵入型輕量級容器的理想
- Spring Framework的宣告式事務管理是建立在Spring的面向切面程式設計(aspect-oriented programming, AOP) 上的
- Spring配置檔案中關於事務配置總是由三個組成部分,分別是DataSource、TransactionManager和代理機制這三部分,無論哪種配置方式,一般變化的只是代理機制這部分