spring知識七------對JDBC的支援
概述
spring框架也是集成了對JDBC資料庫的操作,但是要明白的是spring對JDBC的支援只是一個簡單的封裝,而不是真正意義上的ORM框架,其中最主要的就是Spring對資料庫的操作不支援級聯操作,即對於存在外來鍵關聯的表,查詢資料時,不會連帶查詢。但是spring新增了對資料庫原始檔的配置,這個可以說是簡化了對資料來源的連線。一般情況下我們都會在spring容器管理的基礎上整合Hibernate框架或者ibatis框架。
spring框架對資料庫的封裝分為兩個模板JdbcTemplate 和NamedParameterJdbcTemplate。其中最主要的區別就是NamedParameterJdbcTemplate可以使用具名引數。
具名引數: SQL 按名稱(以冒號開頭)而不是按位置進行指定。 具名引數更易於維護, 也提升了可讀性。具名引數由框架類在執行時用佔位符取代。具名引數只在 NamedParameterJdbcTemplate 中得到了支援 。
JdbcTemplate
首先我們需要在配置檔案中新增我們所需要的配置檔案。
可以看出我們所需要的類是在【org.springframework.jdbc.core】包中
<!-- 配置jdbc模板 JdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" value="#{datasource}"></property>
</bean>
當我們配置好檔案時,我們就可以進行對資料庫的增刪改查了。在這裡一定要注意方法的呼叫。
在查詢時,我們要記得新增POJO類,讓其返回為一個物件,而且要注意使用sql語句的別名與POJO類變數發生一一對映。
不支援級聯查詢,如果一個類中包含了另外一個類變數,則會返回【null 】值。
RowMapper介面 指定如何去對映結果集的行,常用 的實現類是BeanPropertyRowMapper。
JdbcTemplate 類被設計成為執行緒安全的
@Test //單條記錄更新 update(String sql, Object... args)
public void testUpdateSingle(){
String sql = "Update employ set name=? where id=?";
jdbcTemplate.update(sql, "fafa",5);
}
@Test
//批量更新 batchUpdate(String sql, List<Object[]> batchArgs)
/* 注意最後一個引數batchArgs為Object[]的List 型別:
修改一條記錄需要一個Object的陣列,修改多條記錄需要多個Object的陣列,,批量修改則是存放在List中
*/
public void testUpdateBatch(){
String sql = "insert into employ(name,age,sex,departid) values(?,?,?,?)";
List<Object[]> batchArgs =new ArrayList<Object[]>();
batchArgs.add(new Object[]{"AA",15,"男",1});
batchArgs.add(new Object[]{"BB",18,"女",2});
batchArgs.add(new Object[]{"CC",22,"男",1});
jdbcTemplate.batchUpdate(sql, batchArgs);
}
@Test
/*
* 從資料庫中獲取一條記錄就是對應的一個物件
* RowMapper介面 指定如何去對映結果集的行,常用 的實現類是BeanPropertyRowMapper
* 在sql語句中使用別名完成列名與類的屬性名的對映。last_name lastName
* 不支援級聯屬性的查詢,JdbcTemplate 只是簡單的封裝jdbc,不是ORM 框架
*
* queryForObject(String sql, RowMapper<Employ> rowMapper, Object... args)
*/
public void testQueryObject(){
String sql="select id,last_name lastName,age,sex,departid from employ where id=?";
RowMapper<Employ> rowmapper = new BeanPropertyRowMapper(Employ.class);
Employ emp = jdbcTemplate.queryForObject(sql, rowmapper,1);
System.out.println(emp);
}
@Test
//查詢實體類集合,query(String sql, RowMapper<Employ> rowMapper, Object... args)
public void testQueryList(){
String sql = "select id,last_name lastName,age,sex,departid from employ where id>?";
RowMapper<Employ> rowMapper = new BeanPropertyRowMapper(Employ.class);
List<Employ> query = jdbcTemplate.query(sql, rowMapper,5);
System.out.println(query);
}
JdbcDaoSupport
一般在專案中我們在持久層對資料庫進行操作,
Spring JDBC 框架還提供了一個 JdbcDaoSupport 類來簡化 DAO 實現. JdbcDaoSupport 類聲明瞭 jdbcTemplate 屬性, 它可以從 IOC 容器中注入, 或者自動從資料來源中建立。但是不建議這樣使用,因為這樣的使用,在我們利用註解的時候,需要我們手工匯入dataSource或者jdbcTemplate。
在xml中我們可以通過配置檔案進行注入dataSource和jdbcTemplate。而在註解時,沒有辦法自動注入,因為在這裡JdbcDaoSupport對於Set的方法是Final的,不能夠被重寫,只能利用曲線救國。在我們自定義的方法中進行呼叫,然後設定dataSource或者jdbcTemplate。下面是程式碼演示,建議使用第二種方式。
// 在基於註解的時候,不推薦使用JdbcDaoSupport進行工作,而是在dao層引入JdbcTemplate作為其類成員變數
@Repository
public class DepartDAO extends JdbcDaoSupport {
// 在繼承spring的JdbcDaoSupport 時,
//利用註解時要注意引入一個dateSource或者JdbcTemplate 在此類中,否則會進行報錯 利用setter方法進行引入
/* @Autowired
public void SetterDatasource2(DataSource dataSource){
setDataSource(dataSource);
}
*/
@Autowired
public void SetterJdbcTeplate2(JdbcTemplate jdbcTemplate){
setJdbcTemplate(jdbcTemplate);
}
public Depart get(int id){
String sql = "select id,name,people_count peopleCount from depart where id=?";
RowMapper<Depart> rowMapper = new BeanPropertyRowMapper(Depart.class);
return depart;
}
}
// 推薦使用這個模式
@Repository
public class EmployDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
public Employ findEmploy(int id){
String sql="select id,last_name lastName,age,sex,departid from employ where id=?";
RowMapper<Employ> rowmapper = new BeanPropertyRowMapper(Employ.class);
Employ emp = jdbcTemplate.queryForObject(sql, rowmapper,id);
return emp;
}
}
NamedParameterJdbcTemplate
首先我們需要在配置檔案中新增我們所需要的配置檔案。
可以看出我們所需要的類是在【org.springframework.jdbc.core】包中
NamedParameterJdbcTemplate沒有無參的構造器,所以利用一個有參的構造器將DataSource傳遞進去
<!-- 配置 jdbc模板NamedParameterJdbcTemplate 該物件可以使用具名引數 -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="datasource"></constructor-arg>
</bean>
對於NamedParameterJdbcTemplate的使用有兩種方式
方式一是簡單的起引數名稱
方式二是將引數名稱與我們的pojo類欄位名稱一致
@Test
// 使用namedParameterJdbcTemplate模板進行操作資料庫,可以使用具名引數,對於資料的封裝我們放到map中
/* 方式一
*可以為引數取名字,如果有對個引數的話,可以省略對位置的麻煩,直接對應引數名就可以了,便於維護
*但是就是比較麻煩,需要使用map進行資料封裝
*
*update(String sql, Map<String, ?> paramMap)
*/
public void testnamedParameterJdbcTemplate(){
String sql ="insert into depart (name,people_count) values(:ln,:count)";
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("ln", "ff");
paramMap.put("count", 7);
namedParameterJdbcTemplate.update(sql, paramMap);
}
@Test // 使用namedParameterJdbcTemplate模板進行操作資料庫,可以使用具名引數
/* 方式二
*可以為引數取名字,如果使引數名字與我們類中的欄位名稱相對應的話,我們可以進行傳遞類物件
*update(String sql, SqlParameterSource paramSource)
*/
public void testnamedParameterJdbcTemplate02(){
String sql ="insert into depart (name,people_count) values(:name,:peopleCount)";
Depart depart = new Depart();
depart.setName("太極");
depart.setPeopleCount(6);
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(depart);
namedParameterJdbcTemplate.update(sql, paramSource);
}