java EE開發(fā)之Servlet第十一課:反射基礎(chǔ)三

1 .使用反射機制形成通用sql語句

1)構(gòu)建insert語句

public static void save(Object obj) {

// 獲取傳遞過來對象的Class類對象

Class c = obj.getClass();

// 獲取數(shù)據(jù)庫連接

Connection conn = getConn();

// 準備執(zhí)行SQL語句的對象(車何鸡、船)

PreparedStatement pstmt = null;

// 獲取類對象的所有聲明了的屬性

Field[] fs = c.getDeclaredFields();

// 解鎖

Field.setAccessible(fs, true);

// 根據(jù)獲得的類對象冯挎,拼SQL語句

StringBuffer sb = new StringBuffer();

sb.append("insert into ");

// 表名

sb.append(c.getSimpleName());

sb.append(" values( ");

// 拼SQL語句有多少個問號

for (int i = 1; i < fs.length; i++) {

sb.append(" ? ");

if (i < fs.length - 1) {

sb.append(" , ");

}

}

sb.append(" ) ");

try {

// 初始化執(zhí)行SQL語句的對象

pstmt = conn.prepareStatement(sb.toString());

// 給問號進行賦值

for (int i = 1; i < fs.length; i++) {

pstmt.setObject(i, fs[i].get(obj));

}

// 執(zhí)行SQL語句

pstmt.executeUpdate();

} catch (SQLException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} finally {

closeAll(conn, pstmt, null);

}

System.out.println(sb);

}

2)構(gòu)建select語句

public? List<T> queryFX(Class<T> clazz) {

List<T> list = new ArrayList<T>();

// 獲取傳遞過來對象的類對象

//Class c = obj.getClass();

Connection conn = getConn();

PreparedStatement pstmt = null;

ResultSet rs = null;

// 獲取聲明的屬性

Field[] fs = clazz.getDeclaredFields();

// 解鎖

Field.setAccessible(fs, true);

// 拼SQL

StringBuffer sb = new StringBuffer();

sb.append(" select * from tbl_");

sb.append(clazz.getSimpleName());

// 初始化執(zhí)行SQL語句的對象

try {

pstmt = conn.prepareStatement(sb.toString());

rs = pstmt.executeQuery();

// 從結(jié)果集中獲取數(shù)據(jù)

while (rs.next()) {

// Student stu = new Student();

T o = (T) clazz.newInstance();

// stu.setSid(rs.getInt("sid"));

for (int i = 0; i < fs.length; i++) {

// 獲取rs中的值

Object value = rs.getObject(fs[i].getName());

// 獲value值存入到對應(yīng)屬性中xxx.setXxx();

if (value instanceof BigDecimal) {

// 將數(shù)據(jù)中類型為numeric類型的做一個和實體類型對應(yīng)的轉(zhuǎn)換

//value = ((BigDecimal) value).doubleValue();

value = ((BigDecimal) value).intValue();

}

/*

* if(value instanceof Timestamp ){

*? ? ? Timestamp ts =(Timestamp)value;

*? ? ? value = ts.toString();

* }

*/

// rs.getObject()獲得的數(shù)據(jù)類型為時間戳類型

// 需要轉(zhuǎn)換為實體中對應(yīng)的java.sql.Date類型時输吏,需要做以下轉(zhuǎn)換

if (value instanceof Timestamp) {

Timestamp ts = (Timestamp) value;

value = new Date(ts.getTime());

}

// 把值裝入到實體類中屬性中

fs[i].set(o, value);

}

// 將對象放入到list中

list.add(o);

}

} catch (SQLException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} finally {

closeAll(conn, pstmt, rs);

}

return list;

}

注意: 表名和實體類名相同枢舶,表的列名和類的屬性名一樣。

總結(jié):利用同樣的思路幔欧,可以構(gòu)建通用刪除包警,通用更新,讀者自行完成伯顶。

2 .克隆

1)普通屬性不需要克隆

2) 淺度克隆:這個類中的屬性沒有引用另外一個類型的對象

該類必須顯示的繼承Object類和實現(xiàn)Cloneable接口,然后重寫clone();就是把我們要克隆的類,實現(xiàn)一個Cloneable的接口呛踊,接口中無方法,只是一個標識 而已啦撮,然后寫一個方法public void clone();本來是protected的谭网,要改為public 的,這樣才能在非子類中訪問該方法赃春,在main方法中愉择,生成該類的兩個對象,第一個 給他賦值织中,第二個就讓它等于第一個對象的clone方法锥涕,這樣就克隆了,第二個對象的改變不會影響第一個狭吼。

public class GrilFriend implements Cloneable {

........

@Override

public Object clone() throws CloneNotSupportedException {

// TODO Auto-generated method stub

return super.clone();

}

}

3)深度克虏阕埂:這個類中的屬性有引用另外一個類型的對象

淺克隆,只涉及到一個類的克碌篌稀破花;既然有淺克隆也就有深克隆,深克隆疲吸,是指:在第一個類中用到了另外的類作為屬性座每,那樣的話,當?shù)谝粋€類要克隆摘悴,則它所涉及的類則都要標識為克隆的峭梳,并實現(xiàn)從clone方法。

@Override

//procted-->public

public? Object clone() throws CloneNotSupportedException {

//調(diào)用父類的克隆方法

//稱為淺度克隆

//return super.clone();

//做深度克隆

//把用戶克出來

Users u? = (Users)super.clone();

//把用戶女友克出來

GrilFriend gf= (GrilFriend)u.getGf().clone();

//綁定用戶的克隆的對象和女友有克隆對象

u.setGf(gf);

return u;

}

3.序列化

1)序列化作用:

當我們在電腦上玩游戲等一些事情時蹂喻,然而有時我們要去有事葱椭,而此時我們退出游戲捂寿,

會有一個是否保存當前游戲的按鈕,保存的是我們當前游戲的狀態(tài)挫以,例如:當前自己的位置者蠕,怪物的位置等等。

而這時我們就可以用到序列化來解決這個問題

2)序列化是什么:

就是指把java生成的一個對象(包括屬性和方法)掐松,以一種對象輸出流(ObjectOutputStream)的方式踱侣,寫入到硬盤的文件中(writeObject(Object obj)),以后要使用到這個對象大磺,也可以用對象輸入流(ObjectInputStream)的方式讀到程序中抡句,使用(readObject())把文件中的內(nèi)容恢復為一個對象,恢復的對象的數(shù)據(jù)與當初寫入對象的數(shù)據(jù)一至,這樣對像就可以在網(wǎng)絡(luò)中傳輸杠愧,以及像游戲那樣得到自己的位置待榔,怪物的位置等等

3)怎么實現(xiàn)序列化

(1)需要序列化的類必須實現(xiàn)Serializable,但沒有方法需要實現(xiàn),它只是一種標示流济,標示該類可以序列化

(2)建立FileOutputStream锐锣,寫到哪個文件里,再套用ObjectOutputStream绳瘟,調(diào)用writeObject(Object o)序列化對象

(3)建立FileInputStream,讀硬盤的文件雕憔,再套用ObjectInputStream,調(diào)用readObject()恢復對象

(4)可以同時寫多個對象進去,那么每個對象都會給它一個標志位糖声,用來區(qū)別斤彼,讀的時候先進去先出來,后進去后出來(隊列結(jié)構(gòu))

(5)static和transient是不能默認序列化蘸泻,就是指凡是它們修飾的屬性的值不會序列化到文件里面去琉苇,那么讀出來也是為空的

(6)可以通過重寫Serializable接口已經(jīng)注釋的方法

writeObject(ObjectOutputStream out)來序列化static和 transient修飾的屬性的值,通過readObject(ObjectInputStream in)悦施,來讀static和 transient修飾的屬性的值這兩個方法必須是private void 的并扇,在序列化對象和讀對象的時候jdk會自動去調(diào)用這兩個方法,有一些注意事項看代碼抡诞。

完整代碼

public class Users implements Serializable{

.........

//序列化時拜马,static和transient(瞬時態(tài))修飾的變量,不可序列化

private static String email;

private transient String phone;

序列化

Users users = new Users();

users.setUid(1);

users.setUname("tom");

users.setAge(24);

users.setPhone("13888888");

users.setEmail("aa@qq.com");

try {

//創(chuàng)建對象輸出流

ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("users.txt"));

os.writeObject(users);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

反序列化

try {

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("users.txt"));

Users users = (Users)ois.readObject();

System.out.println(users.getUid()+"\t"+users.getUname());

System.out.println(users.getPhone()+"\t"+users.getEmail());

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末沐绒,一起剝皮案震驚了整個濱河市俩莽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌乔遮,老刑警劉巖扮超,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡出刷,警方通過查閱死者的電腦和手機璧疗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來馁龟,“玉大人崩侠,你說我怎么就攤上這事】篱荩” “怎么了却音?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長矢炼。 經(jīng)常有香客問我系瓢,道長,這世上最難降的妖魔是什么句灌? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任夷陋,我火速辦了婚禮,結(jié)果婚禮上胰锌,老公的妹妹穿的比我還像新娘骗绕。我一直安慰自己,他們只是感情好资昧,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布酬土。 她就那樣靜靜地躺著,像睡著了一般榛搔。 火紅的嫁衣襯著肌膚如雪诺凡。 梳的紋絲不亂的頭發(fā)上东揣,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天践惑,我揣著相機與錄音,去河邊找鬼嘶卧。 笑死尔觉,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的芥吟。 我是一名探鬼主播侦铜,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钟鸵!你這毒婦竟也來了钉稍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棺耍,失蹤者是張志新(化名)和其女友劉穎贡未,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡俊卤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年嫩挤,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片消恍。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡岂昭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狠怨,到底是詐尸還是另有隱情约啊,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布取董,位于F島的核電站棍苹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茵汰。R本人自食惡果不足惜枢里,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹂午。 院中可真熱鬧栏豺,春花似錦、人聲如沸豆胸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晚胡。三九已至灵奖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間估盘,已是汗流浹背瓷患。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遣妥,地道東北人擅编。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像箫踩,于是被迫代替她去往敵國和親爱态。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容