JDBC部要求我們掌握其他框架的查詢語言,它是基于SQL這種數(shù)據(jù)訪問語言的。JDBC很多便捷的功能是很多框架不能比的,但是JDBC也不是十全十美的,它具有強大的功能、靈活性和其他一些優(yōu)點,但也有缺點。
傳統(tǒng)的JDBC對數(shù)據(jù)庫的操作,有很多重復(fù)的代碼,這樣給程序員帶來了很多額外的工作量,Spring提供了JDBC模板很好的解決了這個問題,由于傳統(tǒng)的方法比較簡單,在這里不介紹了,直接說模板吧。
使用JDBC模板:
Spring的JDBC框架能夠承擔(dān)資源管理和異常處理的工作。對于JDBC來說,Spring提供了3個模板類
JdbcTemplate:Spring里最基本的JDBC模板,利用JDBC和簡單的索引參數(shù)查詢提供對數(shù)據(jù)庫的簡單訪問。
NamedParameterJdbcTemplate:能夠在執(zhí)行查詢時把值綁定到SQL里的命名參數(shù),而不是使用索引參數(shù)。
SimpleJdbcTemplate:利用Java 5 的特性,比如自動裝箱、通用(generic)和可變參數(shù)類表來簡化JDBC模板的使用。
使用JdbcTemplate來訪問數(shù)據(jù)
只需要配置DataSource就能夠讓JdbcTemplate工作,如下配置:
<!-- 配置DBCP數(shù)據(jù)源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" scope="singleton">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.3.226:3306/spring" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="initialSize" value="5" />
<property name="maxActive" value="10" />
</bean>
<!-- 配置JDBC模板,spring里最基本的JDBC模板,利用JDBC和簡單的索引此參數(shù)查詢提供對數(shù)據(jù)庫的簡單訪問 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
現(xiàn)在我們可以把JdbcTemplate裝配到DAO,使用它來訪問數(shù)據(jù)庫public class JdbcRantDao{
//配置JdbcTemplate
private jdbcTemplate jdbcTemplate;
public void setJdbcTempalte(JdbcTemplate jdbcTempalte) {
this.jdbcTempalte = jdbcTempalte;
}
//寫入Motorist的SQL語句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//獲取所有Motorist的SQL語句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//獲取某一個Motorist的SQL語句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
/**
* 利用JDBC模板往數(shù)據(jù)庫里添加一行數(shù)據(jù)
* @param motorist
*/
public void saveMotorist(Motorist motorist){
jdbcTemplate.update(MOTORIST_INSERT, new Object[] {motorist.getEmail(),motorist.getPassword(),motorist.getFirstName(),motorist.getLastName()});
}
/**
* 利用JDBC模板從數(shù)據(jù)庫中讀取一個數(shù)據(jù)
* @param id
* @return
*/
public Motorist getMotoristById(int id){
List matches = jdbcTemplate.query(MOTORIST_BY_ID_SELECT,
new Object[] {Integer.valueOf(id)},
new RowMapper(){
public Object mapRow(ResultSet rs,int rowNum)
throws SQLException,DataAccessException{
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
});
return matches.size() > 0 ? (Motorist) matches.get(0) : null;
}
}
使用命名參數(shù):使用了索引參數(shù)以為著把參數(shù)傳遞給update()方法時,我們必須注意參數(shù)在查詢里的次數(shù),并且以正確的次序列出相應(yīng)的值。為了避免這種情況,我們可以使用命名參數(shù)。
<!-- 配置JDBC命名模板 ,能夠執(zhí)行查詢時把值綁定到SQL里的命名參數(shù),而不是使用索引參數(shù)-->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
public void saveMotorist(Motorist motorist){
Map parameters = new HashMap();
parameters.put("email", motorist.getEmail());
parameters.put("password", motorist.getPassword());
parameters.put("firstName", motorist.getFirstName());
parameters.put("lastName", motorist.getLastName());
namedParameterJdbcTemplate.update(MOTORIST_INSERT, parameters);
}
在Java5里簡化JDBC:之前傳遞給update()方法的參數(shù)是Object數(shù)組,但是使用java5的新特性,可以不必構(gòu)造Object數(shù)組就可以傳遞參數(shù)。
<!-- 配置JDBC簡單模板 ,利用java5特性,比如自動裝箱、通用和可變參數(shù)到表來簡化JDBC模板的使用-->
<bean id="simpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource" />
</bean>
SimpleJdbcTemplate不僅能支持可變參數(shù)來綁定參數(shù)值,在映射結(jié)果集時還利用了Java 5 對自動裝箱的支持。再看一下下列程序里的getMotoristById(),應(yīng)該注意兩件事:
id參數(shù)必須轉(zhuǎn)化為一個包裹類型(java.lang.Long)才能在Object數(shù)組里進行傳遞。
RowMapper的mapRow()方法的返回類型是java.lang.Object。這是因為RowMapper的通用性要求它支持任何類型的對象,所以返回的結(jié)果的類型是最通用的類型:Object。
package org.spring.source.jdbc.template;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
public class SimpleJdbcRantDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
//寫入Motorist的SQL語句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//獲取所有Motorist的SQL語句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//獲取某一個Motorist的SQL語句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
public void setSimpleJdbcTemplate(SimpleJdbcTemplate simpleJdbcTemplate) {
this.simpleJdbcTemplate = simpleJdbcTemplate;
}
public SimpleJdbcTemplate getSimpleJdbcTemplate() {
return simpleJdbcTemplate;
}
public void saveMotorist(Motorist motorist){
simpleJdbcTemplate.update(MOTORIST_INSERT, motorist.getEmail(), motorist.getPassword(), motorist.getFirstName(), motorist.getLastName());
}
public Motorist getMotoristById(int id){
List<Motorist> matches = getSimpleJdbcTemplate().query(
MOTORIST_BY_ID_SELECT,
new ParameterizedRowMapper<Motorist>(){
public Motorist mapRow(ResultSet rs, int rowNum)
throws SQLException {
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
},
id //顯示id沒有被包裹
);
return matches.size() > 0 ? matches.get(0) : null;
}
}
使用Spring對JDBC的DAO支持類:Spring的JdbcDaoSupport用于編寫基于JDBC的DAO類的基類,我們只需讓自己的DAO類繼承它即可。
package org.spring.source.jdbc.template;
import java.sql.SQLException;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.sql.ResultSet;
public class JdbcRantDao extends JdbcDaoSupport{
//寫入Motorist的SQL語句
private static final String MOTORIST_INSERT =
"insert into motorist(id,email,password,firstName,lastName)values(null,?,?,?,?)";
//獲取所有Motorist的SQL語句
private static final String MOTORIST_SELECT =
"select id,email,password,firstName,lastName from motorist";
//獲取某一個Motorist的SQL語句
private static final String MOTORIST_BY_ID_SELECT =
MOTORIST_SELECT + " where id=?";
/**
* 利用JDBC模板往數(shù)據(jù)庫里添加一行數(shù)據(jù)
* @param motorist
*/
public void saveMotorist(Motorist motorist){
getJdbcTemplate().update(MOTORIST_INSERT, new Object[] {motorist.getEmail(),motorist.getPassword(),motorist.getFirstName(),motorist.getLastName()});
}
/**
* 利用JDBC模板從數(shù)據(jù)庫中讀取一個數(shù)據(jù)
* @param id
* @return
*/
public Motorist getMotoristById(int id){
List matches = getJdbcTemplate().query(MOTORIST_BY_ID_SELECT,
new Object[] {Integer.valueOf(id)},
new RowMapper(){
public Object mapRow(ResultSet rs,int rowNum)
throws SQLException,DataAccessException{
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
});
return matches.size() > 0 ? (Motorist) matches.get(0) : null;
}
}