J2EE中幾種物件導向的資料庫對映訪問策略:
幾種物件導向的資料庫訪問策略:
1 JDBC
是最原始的方法,寫sql語句,維護性差
下面物件導向的方法:
例如update: 要先取出物件,更新物件,然後再儲存
OrderInfo order = orderService.getOrder(orderId);
order.setStatus(new Integer(2));
orderService.updateOrder(order);
2 Hibernate
使用Hql
3 iBatis
將查詢和更新放在maps檔案中
select productid, name, descn, category from product
lower(name) like #keywordList[]# OR lower(category) like #keywordList[]# OR lower(descn) like #keywordList[]#
4 EasyDBO:
有三種實現方法,我們只看其中採用annotation的
@Table(tableName="Customer")
public class Customer implements Serializable {
來確定表名
採用反射的方法,不需要配置檔案:
public List getRootCustomers() {
return this.dao.query(Customer.class,"(parent_id is null or parent_id='')");
}
List list=dao.query(CustomerPrice.class, "customer_id="+cu.getId()+" and product_id="+p.getId()+" order by vdate desc");
該方法已經和ADODB很像了,但和adodb不同的是,仍然沒有實現完全自動的Plain SQL轉換到PO.
5 PHP's ADODB的j2ee移植
以jdbc查詢sql為基礎,通過反射,範型等方法自動裝載。
adodb的方法和上面的easydbo很像,不過在obj到sql的生成上更加成熟一些,驅動也更加多
對於查詢
/////////////////////////////////////////////////////////////////////////////
//Function: 完成ResultSet物件向ArrayList物件為集合的物件的轉化
//Para:sql,指定的查詢Sql
//Para:className,Sql相對應得JavaBean/FormBean類的名字
//Return:以類className為一條記錄的結果集,完成ResultSet物件向ArrayList物件為集//合的className物件的轉化
//////////////////////////////////////////////////////////////////////////////
public ArrayList Select(String sql,String className){
ArrayList paraList=new ArrayList();
try{
if (conn == null){
Connection();
}
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery();
String recordValue="";
Object c1=null;
paraList=new ArrayList();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()){
c1=Class.forName(className).newInstance();
for (int i=1; i<=columnCount; i++) {
if(rs.getString(rsmd.getColumnName(i))!=null){
recordValue=rs.getString(rsmd.getColumnName(i));
}else{
recordValue="";
}
Method m=c1.getClass().getMethod(getSetMethodName(rsmd.getColumnName(i)),new Class[]{recordValue.getClass()});
m.invoke (c1, new Object[]{recordValue});
}
paraList.add(c1);
}
}catch(SQLException ex){
}catch(ClassNotFoundException e){
}catch(NoSuchMethodException e) {
}catch(InvocationTargetException e){
}catch (IllegalAccessException e){
}catch(InstantiationException e){
} finaly{
closeConnection();
return paraList;
}
}
//Function:取得使用者列表
//Para:
//Return:返回使用者列表
/////////////////////////////////////////////////////////////////////////////
public ArrayList getUsers(){
ArrayList ret=null;
DatabaseManage db=new DatabaseManage();
String sql=" select usr_id,usr_name "
+" from users " ; //該方法的好處是SQL可以隨便寫,需要的欄位也可以隨便寫,甚至免去了持久層的LazyLoad
ret=db.Select(sql,"com.domain.User");
return ret;
}
對於單張表,用PO/Formbean來存放
如果有關聯多張表,需要一個VO/Map來存放
對於儲存和更新
檢查物件裡面的每一個屬性,如果不是null,就組成SQL語句,
更新的時候,先查出這個物件,如果屬性不是null,並且屬性值變了,才將該屬性組成SQL語句
這種方法和Hibernate/Ibatis相比可能犧牲一些效能,但是免去了大量的配置檔案,如果對欄位有特殊的要求,可以
通過annotation來定義。
Annotation可是個好東西,根據jdk手冊:Annotations can be read from source files, class files, or reflectively at run time.
所以可以充分利用反射讀取annotation來減少程式碼。
下面是一些例子
@com.acme.util.Name(first=Alfred, middle=E., last=Neuman)
@Table(tableName="Customer")
@ManyToOne(column = "parent_id", fieldType=java.util.HashSet.class,type = Customer.class,lazy=false)
讀取的方法是在反射裡面使用下面的方法
T xxx = getAnnotation(Class annotationClass)
當然,實現必須宣告annotationClass,下面是手冊的一個簡單例子
/**
* Describes the Request-For-Enhancement(RFE) that led
* to the presence of the annotated API element.
定義一個標籤記號
*/
public @interface RequestForEnhancement {
int id();
String synopsis();
String engineer() default "[unassigned]";
String date(); default "[unimplemented]";
}
這個標籤,和它的屬性都在上面宣告瞭,下面是某個函式中需要用到這個標籤的示例
@RequestForEnhancement(
id = 2868724,
synopsis = "Enable time-travel",
engineer = "Mr. Peabody",
date = "4/1/3007"
)
public static void travelThroughTime(Date destination) { ... }
因此我們如果想要呼叫這個標籤
for (Method m : Class.forName('假設是travelThroughTime所在的類名').getMethods()) {
if (m.isAnnotationPresent(RequestForEnhancement.class)) {
RequestForEnhancement rfe = m.getAnnotation(RequestForEnhancement.class);
下面就可以取得rfe的屬性了
}
}
Commons Attributes也是一個替代jdk標準annotation的方案
PHP中的ADODB之所以強大,高效是在於PHP陣列的強大和弱變數定義的方便。
當然這裡的每一個物件就相當於對應資料庫的一張表,這樣也很好。
因為在業務相當複雜的時候,關聯要儘量少用,把業務精心設計在資料庫表上面而非java物件的集合的關聯上。
在大型應用中,一般1:1的關聯都多使用View來處理關聯,1:n和n:n的關聯,建議還是在DAO裡面手動儲存,裝載和更新
===================
此外還有一些方法,可以方便我們快速的將RS變成可操作的物件,簡單舉幾個例子如下
1 commons dbutils
Custom RowProcessor
java.lang.Object[] toArray(java.sql.ResultSet rs)
Convert a ResultSet row into an Object[].
java.lang.Object toBean(java.sql.ResultSet rs, java.lang.Class type)
Convert a ResultSet row into a JavaBean.
java.util.List toBeanList(java.sql.ResultSet rs, java.lang.Class type)
Convert a ResultSet into a List of JavaBeans.
java.util.Map toMap(java.sql.ResultSet rs)
Convert a ResultSet row into a Map.
Custom BeanProcessor
java.lang.Object toBean(java.sql.ResultSet rs, java.lang.Class type)
Convert a ResultSet row into a JavaBean.
java.util.List toBeanList(java.sql.ResultSet rs, java.lang.Class type)
Convert a ResultSet into a List of JavaBeans.
2 commons beanutils
ResultSetDynaClass (Wraps ResultSet in DynaBeans)
Connection conn = ...;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery
("select account_id, name from customers");
Iterator rows = (new ResultSetDynaClass(rs)).iterator();
while (rows.hasNext()) {
DynaBean row = (DynaBean) rows.next();
System.out.println("Account number is " +
row.get("account_id") +
" and name is " + row.get("name"));
}
rs.close();
stmt.close();
============
總得來說,使用反射機制可以極大得方便對資料的各種操作,使操作變得更加透明,無需配置檔案
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1504282
相關文章
- 資料庫訪問幾種方式對比資料庫
- 物件導向:類的定義和繼承的幾種方式物件繼承
- 如何將資料庫中json格式的列值對映到java物件的屬性中資料庫JSONJava物件
- php中的程式導向與物件導向PHP物件
- PHP 物件導向 (七)訪問物件的方式及後期靜態繫結PHP物件
- Golang 中的物件導向Golang物件
- 物件導向-物件導向思想物件
- 問答題:物件導向的思想物件
- java物件導向(中)Java物件
- 程式導向和麵向物件的對比(轉)物件
- 微軟改變資料訪問策略 OLE DB再次轉向ODBCOS微軟
- 在 .NET 中建立物件的幾種方式的對比物件
- SQL Server 資料訪問策略:CLRMESQLServer
- 說下你對物件導向的理解物件
- Spring框架訪問資料庫的兩種方式的小案例Spring框架資料庫
- Redis有哪幾種資料淘汰策略?Redis
- JS 中的物件導向 prototype classJS物件
- JDBC資料庫訪問JDBC資料庫
- PHP設計模式(4)—— 資料物件對映模式PHP設計模式物件
- SQL Server 資料訪問策略:即席SQLCUSQLServer
- 什麼是多型?物件導向中對多型的理解多型物件
- 兄弟連go教程(19)資料 - ⾯物件導向Go物件
- 談談我對物件導向以及類與物件的理解物件
- 02.Java物件導向問題Java物件
- 與面試官談笑風生 | Python物件導向之訪問控制面試Python物件
- 物件導向與程式導向物件
- 程式導向與物件導向物件
- “程序導向”和“物件導向”物件
- 物件導向物件
- day08 Go中的物件導向Go物件
- PHP中物件導向的分頁類PHP物件
- java的物件導向Java物件
- 物件導向,搞定物件物件
- 深入理解物件導向,物件導向3個特性7個原則6種關係物件
- 物件導向:希望可以遇到對的那個人物件
- JAVA物件導向基礎--物件導向介紹Java物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- python中物件導向_類_物件的概念與定義Python物件
- 大資料學習之路——java物件導向(二)大資料Java物件