就JdbcTemplate
上的各個方法來看,它封裝了JDBC處理的細節,讓您不用接觸到底層的資料庫技術,然而JdbcTemplate的各個方法仍須熟悉如何使用SQL語法,
如果您想讓一些程式開發人員不用接觸到SQL語法,在Spring中,您可以進一步建立可重用的操作物件,建立之後在進行資料庫設計時,將這些設計完成的
可重用物件給開發人員使用,他們就無需接觸到SQL的細節,從他們的觀點來看,資料庫操作更接近物件導向的操作方式。
Spring提供org.springframework.jdbc.object套件,讓您以更物件導向的方式來設計資料庫操作方面的程式,您只要事先
繼承或直接實例化相對應的類別並編譯,之後就可以重複利用這個實例,呼叫它的方法來進行資料庫相關操作,而不用接觸SQL等相關細節。
org.springframework.jdbc.object.RdbmsOperation是個抽象類,代表RDBMS(Relational
Database Management
System)的查詢、更新、預存程序等操作,您可以使用其子類org.springframework.jdbc.object.SqlUpdate、
org.springframework.jdbc.object.MappingSqlQuery等類別,它們被設計為執行緒安全(Thread-
safe),所以您可以在多執行緒的環境下重複使用這些類別的實例。
SqlFunction用來調用SQL Function,例如可以調用COUNT(),然後返回一個整數表示查詢到的資料筆數,下面是一個例子:
SqlFunction sf = new SqlFunction(
dataSource, "SELECT COUNT(*) from user");
sf.compile();
sf.run();
RdbmsOperation的子類別在設定好DataSource、SQL以及相關參數後,必須先呼叫compile()進行編譯,之後就可以重複使用這個實例,在設計時可以繼承SqlFunction來封裝SQL,例如修改使用 JdbcTemplate 的內容,新增一個類別如下所示:
package onlyfun.caterpillar;
import javax.sql.DataSource;
import org.springframework.jdbc.object.SqlFunction;
public class UserFunction extends SqlFunction { public UserFunction(DataSource dataSource) { super(dataSource, "SELECT COUNT(*) from user"); compile(); } }
SqlUpdate類別用來表示一個SQL的更新操作,您也可以設定相關參數,設計時也可以繼承它來進行SQL的封裝,例如:
package onlyfun.caterpillar;
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.jdbc.object.SqlUpdate;
public class UserUpdate extends SqlUpdate { public UserUpdate(DataSource dataSource) { super(dataSource, "INSERT INTO user (name,age) VALUES(?,?)"); int[] types = {Types.VARCHAR, Types.INTEGER}; setTypes(types); compile(); } }
setTypes()方法用來設定SQL中"?"佔位字元所要插入的數據類型,之後執行update()方法時,可以僅指定物件陣列作為引數來進行查詢,每一個陣列值將實際取代"?"佔位字元,例如可以這麼使用:
...
SqlUpdate userUpdate = new UserUpdate(dataSource);
...
userUpdate.update(
new Object[] {user.getName(), user.getAge()});
SqlQuery類別表示一個SQL查詢操作,不過通常很少直接使用這個類,因為通常查詢到資料之後,會作一些處理,例如封裝為User類別的實例,您可
以使用它的子類別org.springframework.jdbc.object.MappingSqlMapping來進行這個動作,例如:
package onlyfun.caterpillar;
import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource;
import org.springframework.jdbc.object.MappingSqlQuery;
public class UserQuery extends MappingSqlQuery { public UserQuery(DataSource dataSource) { super(dataSource, "SELECT * FROM user"); compile(); } protected Object mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } }
設計好這個類別之後,您可以這麼使用它:
...
SqlQuery userQuery = new UserQuery(dataSource);
...
List users = userQuery.execute();
執行完execute()方法後,實際上傳回的List中會有User類別的實例,當中並封裝了查詢後的每一筆資料。
配合以上的幾個實作,您可以再改寫一下IUserDAO介面與UserDAO實作,例如:
package onlyfun.caterpillar;
import java.util.List;
public interface IUserDAO { public void insert(User user); public List allUser(); public int count(); }
假設您是程式開發人員,有其它的負責資料庫存取方面的程式,並提供了以上的UserFunction、UserUpdate與UserQuery類別,則
您可以不用關心實際的SQL是如何下達的,可以使用UserFunction、UserUpdate與UserQuery類別來設計您的UserDAO類
別:
package onlyfun.caterpillar;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.object.SqlFunction; import org.springframework.jdbc.object.SqlQuery; import org.springframework.jdbc.object.SqlUpdate;
public class UserDAO implements IUserDAO { private SqlUpdate userUpdate; private SqlQuery userQuery; private SqlFunction userFunction;
public void setDataSource(DataSource dataSource) { userUpdate = new UserUpdate(dataSource); userQuery = new UserQuery(dataSource); userFunction = new UserFunction(dataSource); } public void insert(User user) { userUpdate.update( new Object[] {user.getName(), user.getAge()}); }
public List allUser() { return userQuery.execute(); }
public int count() { return userFunction.run(); } }
將SQL封裝重用之後,從UserDAO程式撰寫的角度來看,完全是物件操作的方式來進行,配合程式的修改,可以寫個簡單的程式來看看運作是否正常:
package onlyfun.caterpillar;
import org.springframework.context.ApplicationContext; import org.springframework.context. support.FileSystemXmlApplicationContext; import java.util.List;
public class SpringDAODemo { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext( "beans-config.xml"); User user = new User(); user.setName("just933"); user.setAge(new Integer(26)); IUserDAO userDAO = (IUserDAO) context.getBean("userDAO"); userDAO.insert(user); System.out.println("筆數: " + userDAO.count()); List list = userDAO.allUser(); for(int i = 0; i < list.size(); i++) { User next = (User) list.get(i); System.out.println("\n\tId:\t" + next.getId()); System.out.println("\tName:\t" + next.getName()); System.out.println("\tAge:\t" + next.getAge()); } } }
|