更新時(shí)間:2022-01-06 10:02:59 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1078次
介紹
O/R 工具的一個(gè)典型問(wèn)題是數(shù)據(jù)類(lèi)型不匹配:域模型中的類(lèi)具有布爾類(lèi)型的屬性,但相應(yīng)的數(shù)據(jù)庫(kù)表將此屬性存儲(chǔ)在BIT或 int類(lèi)型的列中。
這個(gè)例子解釋了 OJB 如何允許你定義 FieldConversions來(lái)正確轉(zhuǎn)換類(lèi)型和值。
此示例的源代碼包含在 OJB 源代碼分發(fā)中并駐留在測(cè)試包 org.apache.ojb.broker 中。
問(wèn)題
測(cè)試類(lèi) org.apache.ojb.broker.Article包含一個(gè)布爾類(lèi)型的屬性 isSelloutArticle:
public class Article implements InterfaceArticle
{
protected int articleId;
protected String articleName;
// maps to db-column Auslaufartikel of type int
protected boolean isSelloutArticle;
...
}
對(duì)應(yīng)表使用 int 列 ( Auslaufartikel ) 來(lái)存儲(chǔ)此屬性:
CREATE TABLE Artikel (
Artikel_Nr INT PRIMARY KEY,
Artikelname CHAR(60),
Lieferanten_Nr INT,
Kategorie_Nr INT,
Liefereinheit CHAR(30),
Einzelpreis DECIMAL,
Lagerbestand INT,
BestellteEinheiten INT,
MindestBestand INT,
Auslaufartikel INT
)
解決方案
OJB 允許使用預(yù)定義(或自寫(xiě))的 FieldConversions 進(jìn)行適當(dāng)?shù)挠成洹T?FieldConversion接口聲明了兩個(gè)方法: javaToSql(...)和 sqlToJava(...) :
/**
* FieldConversion 聲明了一個(gè)協(xié)議,用于類(lèi)型和值
* 持久類(lèi)屬性和
RDBMS的列之間的轉(zhuǎn)換。
* 默認(rèn)實(shí)現(xiàn)不修改其輸入。
* OJB 用戶可以使用預(yù)定義的實(shí)現(xiàn),也可以
* 構(gòu)建他們自己的執(zhí)行任意映射的轉(zhuǎn)換。
* 映射必須在 xml 存儲(chǔ)庫(kù)中定義
* 在字段描述符中。
*
* @author Thomas Mahler
*/
public interface FieldConversion extends Serializable
{
/**
* 將 Java 對(duì)象轉(zhuǎn)換為其 SQL
* 掛件,用于插入和更新
*/
公共抽象對(duì)象 javaToSql(Object source) 拋出 ConversionException;
/**
* 將 SQL 值轉(zhuǎn)換為 Java 對(duì)象,用于 SELECT
*/
public abstract Object sqlToJava(Object source) throws ConversionException;
}
方法 FieldConversion.sqlToJava()是一個(gè)回調(diào),當(dāng)從 JDBC 結(jié)果集中讀入對(duì)象屬性時(shí),它會(huì)在 OJB 代理中調(diào)用。如果 OJB 檢測(cè)到為持久類(lèi)屬性聲明了 FieldConversion,則它使用 FieldConversion 來(lái)執(zhí)行此屬性的編組。
對(duì)于上面提到的將 int 列映射到 boolean 屬性的問(wèn)題,我們可以使用預(yù)定義的 FieldConversion Boolean2IntFieldConversion。看看代碼,看看它是如何工作的:
public class Boolean2IntFieldConversion 實(shí)現(xiàn) FieldConversion
{
private static Integer I_TRUE = new Integer(1);
私有靜態(tài)整數(shù) I_FALSE = 新整數(shù)(0);
私有靜態(tài)布爾 B_TRUE = 新布爾(真);
私有靜態(tài)布爾 B_FALSE = 新布爾(假);
/**
* @see FieldConversion#javaToSql(Object)
*/
public Object javaToSql(Object source)
{
if (source instanceof Boolean)
{
if (source.equals(B_TRUE))
{
return I_TRUE;
}
其他
{
返回 I_FALSE;
}
}
else
{
返回源;
}
}
/**
* @see FieldConversion#sqlToJava(Object)
*/
public Object sqlToJava(Object source)
{
if (source instanceof Integer)
{
if (source.equals(I_TRUE))
{
return B_TRUE;
}
else
{
返回 B_FALSE;
}
}
其他
{
返回源;
}
}
}
org.apache.ojb.broker.accesslayer.conversions 包中定義了其他有用的標(biāo)準(zhǔn)轉(zhuǎn)換 :當(dāng)然,可以使用轉(zhuǎn)換在java.sql.date和 java.util.date之間進(jìn)行映射 。一個(gè)非常有趣的轉(zhuǎn)換是 Object2ByteArrFieldConversion 它允許在 varchar 列中存儲(chǔ)內(nèi)聯(lián)對(duì)象!
回到我們的例子,只剩下一件事要做:我們必須告訴 OJB為文章類(lèi)使用正確的 FieldConversion。這是在 XML 存儲(chǔ)庫(kù)文件中完成的。該字段描述符 允許定義轉(zhuǎn)換屬性聲明完全限定 FieldConversion類(lèi):
<!-- test.ojb.broker.Article 的定義 -->
<class-descriptor
class="org.apache.ojb.broker.Article"
proxy="dynamic"
table="Artikel"
> ...
<field-描述符
名稱(chēng)="isSelloutArticle"
column="Auslaufartikel"
jdbc-type="INTEGER"
conversion="org.apache.ojb.broker.accesslayer.conversions.Boolean2IntFieldConversion"
/>
...
</class-descriptor>
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743