Hibernate SessionFactory 線程安全、重量級,應用程式僅需一個實例;Session 非線程安全,需按請求/執行緒隔離。常見模式為 ThreadLocal + 單例 SessionFactory。
package dao;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
public class HibernateSessionFactory {
private final ThreadLocal<Session> threadLocal = new ThreadLocal<>();
private Configuration configuration = new Configuration();
private SessionFactory sessionFactory;
// 指定配置檔(預設 hibernate.cfg.xml)
public void setConfiguration(String configFile) {
this.configuration = new Configuration().configure(configFile);
this.sessionFactory = null; // 重置,下次重建
}
// 取得當前執行緒 Session
public Session getSession() throws HibernateException {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) rebuildSessionFactory();
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
// 重建 SessionFactory(配置變更時呼叫)
public void rebuildSessionFactory() {
try {
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
// 關閉當前執行緒 Session
public void closeSession() throws HibernateException {
Session session = threadLocal.get();
threadLocal.set(null);
if (session != null) session.close();
}
public SessionFactory getSessionFactory() { return sessionFactory; }
public Configuration getConfiguration() { return configuration; }
}
// DAO 中
Session session = HibernateSessionFactory.getInstance().getSession();
Transaction tx = session.beginTransaction();
try {
// CRUD 操作
tx.commit();
} catch (Exception e) {
tx.rollback();
throw e;
} finally {
HibernateSessionFactory.getInstance().closeSession();
}
Parcelable 是 Android 高效能序列化介面,適用於 Intent、Bundle、AIDL 跨進程傳遞。需實作 writeToParcel、describeContents 並提供 CREATOR。
// Person 實作 Parcelable(省略 writeToParcel/CREATOR 樣板碼)
public void sendPerson() {
Person p = new Person("王海康", "男", 45);
Intent intent = new Intent(this, PersonTest.class);
Bundle bundle = new Bundle();
bundle.putParcelable("person_key", p);
intent.putExtras(bundle);
startActivity(intent);
}
public Person receivePerson() {
return getIntent().getParcelableExtra("person_key");
}
public void sendPersonList() {
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("王海康", "男", 45));
list.add(new Person("薛岳", "男", 15));
Intent intent = new Intent(this, PersonTest.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("person_list_key", list); // 必須用 ArrayList
intent.putExtras(bundle);
startActivity(intent);
}
public ArrayList<Person> receivePersonList() {
return getIntent().getParcelableArrayListExtra("person_list_key");
}
利用 Bundle.putParcelableArrayList 接受 ArrayList<? extends Parcelable>,將任意物件包裝在單元素列表中傳遞(非標準用法,視 Android 版本行為可能異):
// 發送端
ArrayList<Object> wrapper = new ArrayList<>();
wrapper.add(anyObjectList); // anyObjectList 為 List<CustomObject>
bundle.putParcelableArrayList("wrapper_key", wrapper);
// 接收端
ArrayList<Object> wrapper = bundle.getParcelableArrayList("wrapper_key");
List<CustomObject> restored = (List<CustomObject>) wrapper.get(0);
警告:此做法依賴實作細節,可能在未來版本失效,建議正規實作 Parcelable 或改用 JSON/Protobuf 序列化。
| 特性 | Parcelable | Serializable |
|---|---|---|
| 效能 | 高(原生 C++ 實作) | 低(反射 + IO) |
| 實作複雜度 | 需手寫樣板碼(Android Studio 可自動產生) | 僅實作介面 |
| 適用範圍 | Intent/Bundle/AIDL 跨進程 | 一般 Java 序列化、網路傳輸、磁碟儲存 |