Spring in Action 筆記(II) part II
下面是測試Spring提高的Jdbc功能的主要測試類, 測試了一些使用JDBC操作數據的常用功能, 其他沒有測試的請查看其Doc,TestJdbcTemplate.java
package?
test.jdbc;
import?
java.sql.CallableStatement;
import?
java.sql.PreparedStatement;
import?
java.sql.ResultSet;
import?
java.sql.SQLException;
import?
java.sql.Types;
import?
java.util.List;
import?
org.springframework.dao.DataAccessException;
import?
org.springframework.jdbc.core.BatchPreparedStatementSetter;
import?
org.springframework.jdbc.core.CallableStatementCallback;
import?
org.springframework.jdbc.core.JdbcTemplate;
import?
org.springframework.jdbc.core.RowCallbackHandler;
import?
org.springframework.jdbc.core.RowMapper;
import?
org.springframework.jdbc.core.RowMapperResultSetExtractor;
public?class?
TestJdbcTemplate?{
??
public?static?final?
String?strGetTest?=?
"SELECT?*?FROM?APP.test?WHERE?ID?=??"
;
??
private?static?final?
String?strInsertIntoTestTeble?=?
"INSERT?INTO?APP.test?(id,?name)??VALUES?(?,??)"
;
??
??
private?
JdbcTemplate?jdbcTemplate;
??
??
public?
TestJdbcTemplate()?{}
??
public?
TestJdbcTemplate(JdbcTemplate?jdbcTemplate)?{
????
this
.jdbcTemplate?=?jdbcTemplate;
??
}
??
public?
JdbcTemplate?getJdbcTemplate()?{
????
return?
jdbcTemplate;
??
}
??
public?void?
setJdbcTemplate(JdbcTemplate?jdbcTemplate)?{
????
this
.jdbcTemplate?=?jdbcTemplate;
??
}
??
??
/**??測試?插入數據*/
??
public?void?
insertTestData(
int?
id,String?name)?{
????
Object[]?params?=?
new?
Object[]?{id,name};
????
jdbcTemplate.update(strInsertIntoTestTeble,?params);
????
System.out.println(
"插入數據成功!"
);
??
}
??
/**??測試?插入數據*/
??
public?void?
insertTestDataWithTypeChecked(
int?
id,String?name)?{
????
Object[]?params?=?
new?
Object[]?{id,name};
????
int
[]?types?=?
new?int
[]?{Types.INTEGER,Types.VARCHAR};
????
jdbcTemplate.update(strInsertIntoTestTeble,?params,?types);
????
System.out.println(
"插入數據成功(with?Types?checked)!"
);
??
}
??
/**??測試?批量插入數據*/
??
public?void?
insertTestDataByBatchInsert(
final?
List<TestData>?datas)?{
????
//構造?BatchPreparedStatementSetter
????
BatchPreparedStatementSetter?setter?=?
new?
BatchPreparedStatementSetter()?{
??????
public?int?
getBatchSize()?{
????????
return?
datas.size();
??????
}
??????
public?void?
setValues(PreparedStatement?ps,?
int?
index)?{
????????
TestData?data?=?datas.get(index);
????????
try?
{
??????????
ps.setInt(
1
,?data.id);???
//?從1?開始......
??????????
ps.setString(
2
,?data.name);
????????
}?
catch?
(SQLException?e)?{
??????????
//?TODO?Auto-generated?catch?block
??????????
e.printStackTrace();
????????
}
??????
}
????
};
????
jdbcTemplate.batchUpdate(strInsertIntoTestTeble,?setter);
????
System.out.println(
"批量插入數據成功!"
);
??
}
??
/**
???
*?測試?JdbcTemplate
???
*?
@param?
id
???
*/
??
public?void?
getTestData(
final?int?
id)?{
????
final?
Object[]?params?=?
new?
Object[]?{id};
????
????
jdbcTemplate.query(strGetTest,?params,?
new?
RowCallbackHandler()?{
??????
public?void?
processRow(ResultSet?rs)?
throws?
SQLException?{
????????
//?TODO?Auto-generated?method?stub
????????
System.out.println(
"測試JdbcTemplate::?name:"?
+?rs.getString(
2
));
??????
}
??????
????
});
??
}
??
??
/**?測試RowMapper?和?RowMapperResultReader?接口*/
??
public?void?
getDataUsingRowMapper(
int?
id)?{
????
List?datas?=?jdbcTemplate.query(
"SELECT?*?FROM?APP.test?WHERE?ID?=?"?
+?id,?
new?
RowMapper()?{
??????
//?實現RowMapper接口,?來映射每一行數據
??????
public?
Object?mapRow(ResultSet?rs,?
int?
index)?
throws?
SQLException?{
????????
//?TODO?Auto-generated?method?stub
????????
System.out.println(
"測試RowMapper?接口:?name?"?
+?rs.getString(
2
));
????????
return?null
;
??????
}
??????
????
});
????
//datas?中保存查詢結果
????
System.out.println(datas.size());
??
}
??
??
public?
TestData?getDataUsingRowMapperResultReader(
final?int?
id)?{
????
final?
Object[]?params?=?
new?
Object[]?{id};
????
//?TODO?有問題.......
????
TestData?data?=??(TestData)?jdbcTemplate.query(strGetTest,params,new?RowMapperResultSetExtractor(
new?
RowMapper()?{
??????
public?
Object?mapRow(ResultSet?rs,int?index)?
throws?
SQLException?{
????????
TestData?tdata?=?
new?
TestData();
????????
tdata.id?=?rs.getInt(
1
);
????????
tdata.name?=?rs.getString(
2
);
????????
return?
tdata;
??????
}
????
}));
????
????
return?
data;
??
}
??
??
/**?測試調用存儲過程..*/
??
public?void?
testCallableStatement()?{
????
//?使用?CallableStatementCallback?回調接口?調用存儲過程.
????
CallableStatementCallback?cb?=?
new?
CallableStatementCallback()?{
??????
public?
Object?doInCallableStatement(CallableStatement?cs)?
throws?
SQLException,?DataAccessException?{
????????
cs.execute();
????????
return?null
;
??????
}
????
};
????
//?GET_DATA?為存儲過程名
????
jdbcTemplate.execute(
"{?GET_DATA}"
,?cb);
??
}
??
??
??
//?用對象操作數據,?使用SqlUpdate接口.?見?InsertData?類,,,,,
??
//?有容器注入?InsertData.
??
private?
InsertData?insertData?;
??
public?int?
insertTestData(TestData?data)?{
????
return?
insertData.insert(data);
??
}
??
public?
InsertData?getInsertData()?{
????
return?
insertData;
??
}
??
public?void?
setInsertData(InsertData?insertData)?{
????
this
.insertData?=?insertData;
??
}
??
//測試插入數據
??
public?void?
insertDataUsingSqlUpdate(TestData?data)?{
????
insertData.insert(data);
????
System.out.println(
"使用SqlUpdate接口插入數據?成功....."
);
??
}
??
??
/**?和上面使用SqlUpdate接口一樣?把操作創建為對象來操作*/
??
private?
QueryDataById?queryDataById;
??
public?void?
setQueryDataById(QueryDataById?queryDataById)?{
????
this
.queryDataById?=?queryDataById;
??
}
??
//測試
??
public?
TestData?getDataUsingMappingSqlQuery(
int?
id)?{
????
Object[]?params?=?
new?
Object[]?{id};
????
return?
(TestData)?queryDataById.execute(params).get(
0
);
??
}
??
//使用上面兩種方法來插入和查詢數據,不用和JDBC?API交互,?有Spring提供了
??
//中間代理層
??
}
|
下面是函有main函數的 主類. TestApp.java
package?
test.jdbc;
import?
java.util.ArrayList;
import?
java.util.List;
import?
org.springframework.context.ApplicationContext;
import?
org.springframework.context.support.ClassPathXmlApplicationContext;
public?class?
TestApp?{
??
/**
???
*?
@param?
args
???
*/
??
public?static?void?
main(String[]?args)?{
????
DatabaseUtils?dataUtils?=?
new?
DatabaseUtils();
????
dataUtils.connect();
????
System.out.println(
"Open?database:!"
);
????
//?TODO?Auto-generated?method?stub
????
//測試連接數據源?......
????
ApplicationContext?context?=?
new?
ClassPathXmlApplicationContext(
"test/jdbc/spring-traning.xml"
);
????
/*?測試?DataSource?配置*/
????
TestDataSource?ds?=?(TestDataSource)?context.getBean(
"dataBean"
);
????
ds.testDataSource();
????
/*?測試JdbcTemplate?配置*/
????
????
TestJdbcTemplate?tjt?=?(TestJdbcTemplate)?context.getBean(
"testJdbcTemplate"
);
????
tjt.insertTestData(
2
,?
"test?name2"
);
????
tjt.insertTestDataWithTypeChecked(
3
,?
"test?name?3"
);
????
List<TestData>?datas?=?
new?
ArrayList<TestData>();
????
datas.add(
new?
TestData(
4
,
"test?name?4"
));
????
datas.add(
new?
TestData(
5
,
"test?name?5"
));
????
datas.add(
new?
TestData(
6
,
"test?name?6"
));
????
tjt.insertTestDataByBatchInsert(datas);
????
tjt.getTestData(
1
);
????
tjt.getTestData(
2
);
????
tjt.getTestData(
5
);
????
tjt.getDataUsingRowMapper(
5
);
//TODO?類型轉換錯誤.????TestData?data?=?tjt.getDataUsingRowMapperResultReader(1);
//????System.out.println("測試使用?RowMapperResultSetExtractor?讀取一行數據:?"?+?data.id?+?":::?name?"?+?data.name);
????
TestData?tdata?=?
new?
TestData(
9
,
"TestSqlUpdate."
);
????
tjt.insertDataUsingSqlUpdate(tdata);??
//?插入數據
????
????
tjt.getDataUsingRowMapper(
9
);?
//?測試上面插入的數據是否成功
????
????
????
dataUtils.disconnect();
??
}
}
JDBC配置文件:jdbc.properties
# Sample ResourceBundle properties file
db.username=
addressuser
db.password=
addressuser
db.driver=
org.apache.derby.jdbc.EmbeddedDriver
db.url=
jdbc
:
derby:
db.table=
test
db.schema=
APP
db.urlName=
jdbc
:
derby:test
最后是最重要的配置文件: spring-traning.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!
DOCTYPE
beans
PUBLIC
"-//SPRING//DTD BEAN//EN"
"spring-beans.dtd"
>
<
beans
>
<
bean
id
=
"propertyConfigurer"
class
=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>
<
property
name
=
"location"
>
<
value
>
test/jdbc/jdbc.properties
</
value
>
</
property
>
</
bean
>
<!-- get dataSource,配置dataSource -->
<!-- 從JNDI得到DataSource -->
<!-- bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/myDataSource</value>
</property>
</bean> -->
<!-- 使用Spring中的 DriverManagerDataSource -->
<!-- bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${db.driver}</value>
</property>
<property name="url">
<value>${db.urlName}</value>
</property>
<property name="username">
<value>${db.username}</value>
</property>
<property name="password">
<value>${db.password}</value>
</property>
</bean -->
<!-- 使用DBCP dataSource -->
<
bean
id
=
"dataSource"
class
=
"org.apache.commons.dbcp.BasicDataSource"
>
<
property
name
=
"driverClassName"
>
<
value
>
${db.driver}
</
value
>
</
property
>
<
property
name
=
"url"
>
<
value
>
${db.urlName}
</
value
>
</
property
>
<
property
name
=
"username"
>
<
value
>
${db.username}
</
value
>
</
property
>
<
property
name
=
"password"
>
<
value
>
${db.password}
</
value
>
</
property
>
</
bean
>
<
bean
id
=
"dataBean"
class
=
"test.jdbc.TestDataSource"
>
<
property
name
=
"dataSource"
>
<
ref
bean
=
"dataSource"
/>
</
property
>
</
bean
>
<!-- ################################################################# -->
<!-- 配合DataSource測試JdbcTemplate -->
<
bean
id
=
"jdbcTemplate"
class
=
"org.springframework.jdbc.core.JdbcTemplate"
>
<
property
name
=
"dataSource"
>
<
ref
bean
=
"dataSource"
/>
</
property
>
</
bean
>
<
bean
id
=
"testJdbcTemplate"
class
=
"test.jdbc.TestJdbcTemplate"
>
<
constructor-arg
>
<
ref
bean
=
"jdbcTemplate"
/>
</
constructor-arg
>
<!-- 測試 SqlUpdate 接口... -->
<
property
name
=
"insertData"
>
<
ref
bean
=
"insertDataUsingSqlUptate"
/>
</
property
>
</
bean
>
<!-- 測試SqlUpdate......接口 -->
<
bean
id
=
"insertDataUsingSqlUptate"
class
=
"test.jdbc.InsertData"
>
<
constructor-arg
>
<
ref
bean
=
"dataSource"
/>
</
constructor-arg
>
</
bean
>
</
beans
>
ok, Jdbc測試的代碼就結束了.
在這里主要學習了,Spring提高的使用Jdbc的一些包裝類和接口, 來更方便的使用Jdbc操作數據, 不用些那么一些煩人的 try ... catch...... finally.....
感覺使用Sprig效率是很好,代碼看起來也很優美哦. 呵呵:
ok ,今天就終結完了, 下一次看看在Spring中如何高效使用Hibernate吧, 下次見啦