1.關系模型
關系模型把世界看作是由實體(Entity)和聯系(Relationship)構成的;在關系模型中實體通常是以表的形式來表現的。表的每一行描述
實體的一個實例,表的每一列描述實體的一個特征或屬性;所謂聯系就是指實體之間的關系,即實體之間的對應關系;
2.ORM-對象關系映射
ORM是通過使用描述對象和數據庫之間映射的元數據,將java程序中的對象自動持久化到關系數據庫中;它實現了Java應用中的對象到關系數據庫中的表的自動的(和透明的)持久化;當你開發一個應用程序的時候(不使用O/R Mapping),你可能會寫不少數據訪問層的代碼,用來從數據庫保存,刪除,讀取對象信息等。而這些代碼寫起來總是重復的。
個人建議:可以去看看Spring的JdbcTemplate
3.Hibernate-
提供了強大的對象和關系數據庫映射以及查詢功能。
持久化Java類必須遵循的原則:
對JavaBeans風格的屬性實行持久化/getter/setter/
默認的構造方法->Constructor.newInstance()
集合類型的屬性,它的類型必須定義為集合的接口
提供一個標識屬性(identifier property)->如級聯更新等(更新主鍵值的操作,該值由其它表的現有行中的外鍵列引用。在級聯更新中,更新所有外鍵值以與新的主鍵值相匹配)
......
持久化類(POJO)- *.hbm.xml -數據庫結構(schema)【xdoclet/hbm2java(code generator)/SchemaExport(hbm2dll)/Middlegen】
配置Hibernate:
開發hibernate3.0必須的包:
hibernate3.jar
required:antlr、dom4j、CGLIB、asm、Commons Collections、Commons Logging、 EHCache->oscache
Hibernate底層還需要Java Transaction API-jta.jar
將\etc目錄下的log4j.properties復制至Hibernate項目的Classpath下,并修改一下當中的log4j.logger.org.hibernate為error,也就是只在在錯誤發生時顯示必要的訊息
配置文件.xml/.properties
hibernate.cfg.xml:
1
<?xml version="1.0" encoding="utf-8"?>
2
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
3
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
4
<hibernate-configuration>
5
<session-factory>
6
<!-- 顯示實際操作數據庫時的SQL -->
7
<property name="show_sql">true</property>
8
<!-- SQL方言,這邊設定的是MySQL -->
9
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
10
<!-- JDBC驅動程序 -->
11
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
12
<!-- JDBC URL -->
13
<property name="connection.url">jdbc:mysql://localhost/demo</property>
14
<!-- 數據庫使用者 -->
15
<property name="connection.username">root</property>
16
<!-- 數據庫密碼 -->
17
<property name="connection.password">root</property>
18
<!-- 以下設置對象與數據庫表格映像文件 -->
19
</session-factory>
20
</hibernate-configuration>
21
*.hbm.xml-告訴 Hibernate您所定義的*實例如何映射至數據庫表,以Use為例:user.hbm.xml-
1
<?xml version="1.0" encoding="utf-8"?>
2
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
3
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
<hibernate-mapping>
5
<class name="com.db.hibernate.demo.User" table="user">
6
<id name="id" column="id" type="java.lang.Integer">
7
<!-- 主鍵的生成方式由Hibernate根據數據庫Dialect的定義來決定 -->
8
<generator class="native" />
9
</id>
10
<property name="name" column="name" type="java.lang.String" />
11
<property name="age" column="age" type="java.lang.Integer" />
12
</class>
13
</hibernate-mapping>
14
需要在Hibernate配置文件hibernate.cfg.xml中指明映像文件的位置
詳見eclipse的db工程
4.配置文件的問題:
1.The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collection-cache)*,event*,listener*)".
解決:1.可能是文件編碼問題;我的hibernate.cfg.xml是從ppt拷貝出來的,文件編碼有問題;從正確的機器上拷貝一份文件或
者嘗試重新編碼或者從網上拷貝一份正確的然后修改(正確的方法是參考etc目錄下的xml模板)
2.可能是元素(element type)的順序問題
3.可以將hibernate-configuration-3.0.dtd下載下來,對比一下,看哪里出錯
2.hibernate.cfg.xml和*.hbm.xml目前只能放到src根目錄下,放到其他目錄總報錯
3.關于xml dtd,正常下載的jar包中都會有dtd文件的,如hibernate-configuration-3.0.dtd;dom4j解析的時候會優先驗證本地,如果本地有,則不會連接dtd指定的服務器地址;如果沒有的話,可以去那地址下載dtd,放在本地或者將地址改為本地dtd的位置;當然eclipse也由一個選項,window->preference->xml catalog,可以添加;詳見xml選項
5.Criteria
Criteria對SQL進行封裝,對于不甚了解SQL的開發人員來說,使用Criteria也可以輕易的進行各種數據的檢索;Expression設定查詢條件(Expression已被廢棄,eclipse中添加hibernate的javadoc,方便查看)Criteria是對象導向式的查詢方式,讓不了解SQL的開發人員也可以輕易進行各項查詢;但Criteria的API目前還不是很完善;Hibernate鼓勵的查詢方式,是透過HQL(Hibernate Query Language)來進行.
6.Query接口
7.hibernate配置文件-hibernate.cfg.xml(提供較好的結構與配置方式,hibernate建議使用,默認)/hibernate.properties
注意:XML配置文件的位置必須在Classpath下;默認的XML配置文件名稱是hibernate.cfg.xml;你可以自己指定配置文件:
new Configuration().configure().configure("db.cfg.xml");
在Hibernate下載檔案中的etc目錄下,有hibernate.cfg.xml與hibernate.properties可供設定參考properties檔案中不包括映射文件的名稱,需要編程方式:
Configuration cfg = new Configuration().addClass("user.hbm.xml") .addClass(com.db.hibernate.demo.User.class);
hibernate.properties:
hibernate.show_sql = true
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class = com.mysql.jdbc.Driver
hibernate.connection.url = jdbc:mysql://localhost/demo
hibernate.connection.username = root
hibernate.connection.password = root
8.Configuration-
Configuration的實例管理Hibernate的配置信息,通常用于建立SessionFactory
SessionFactory sessionFactory = config.buildSessionFactory();
9.SessionFactory-
SessionFactory一旦建立,就被賦予當時Configuration的配置信息;即使改變Configuration也不會影響之前已建立的該實例,而會新建SessionFactory中包括了數據庫配置及映射關系,它的建立相當復雜,所以使用時需考慮到重用已建立的SessionFactory實例SessionFactory是被設計為線程安全的(Thread-safe)
10.設定數據庫連接-
設定connection.pool_size是Hibernate默認的連接池設定;通常只用于開發階段測試之用
<!-- Hibernate 預設的Connection pool -->
<property name="connection.pool_size">2</property>
使用C3P0連接池,需要包含c3p0-*.jar;也可以使用Proxool或DBCP連接池(etc目錄hibernate.properties中的配置例子來參考)使用Tomcat的話,您也可以通過它提供的DBCP連接池來取得連接-配置中加入connection.datasource屬性
11.hibernate緩存
Hibernate中Session level緩存會在使用主鍵加載資料或是延遲初始(Lazy Initialization) 時作用Session level緩存,Session會維護一個Map容器
通過evict()將某個對象從緩存中移去,可以使用clear()清除緩存中的所有對象
可以通過session的load方法和==來判斷是否存在緩存
Session在使用save()儲存對象時,會將要儲存的對象納入Session level緩存管理,在進行大量數據儲存時,緩存中的實例大量增加最后會導致OutOfMemoryError,可以每隔一段時間使用Session的 flush()強制儲存對象,并使用clear()清除緩存
1
1 Session session = sessionFactory.openSession();
2
2 Transaction tx = session.beginTransaction();
3
3 while(.)
4
4
{
5
5 // 大量加載對象時的循環示意
6
6 .
7
7 session.save(someObject);
8
8 if(count % 100 == 0)
9
9
{
10
10 // 每100筆資料
11
11 session.flush();
12
12 // 送入數據庫
13
13 session.clear();
14
14 // 清除緩存
15
15 }
16
16 }
17
17 tx.commit();
18
18 session.close();
19
配置中hibernate.jdbc.batch_size來控制每多少筆資料就送至數據庫(MySQL中則不支持這個功能,sqlserver/oracle支持)
12.事務
事務是一組原子(Atomic)操作(一組SQL執行)的工作單元;事務中的所有原子操作,不是全部執行成功,就是全部失敗(即使只有一個失敗,所有的原子操作也要全部撤消(回滾))JDBC中通過Connection的setAutoCommit和Commit方法管理事務,異常則回滾;Hibernate本身沒有事務管理功能,它依賴于JDBC或JTA(java transaction api)的事務管理功能;默認是使用JDBC事務管理
配置中添加:hibernate.transaction.factory_class屬性來指定Transaction的工廠類別
<property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JDBCTransactionFactory</property>
Hibernate基于JDBC的事務管理只是對JDBC作了個簡單的封裝:
1
try
2
{
3
session = sessionFactory.openSession();
4
Transaction tx = session.beginTransaction();
5
.
6
tx.commit(); // 必須commit才會更新數據庫
7
}
8
catch(HibernateException e)
9
{
10
tx.rollback();
11
}
在一開始的openSession()取得Session時,JDBC的Connection實例之AutoCommit就被設定為false,在 beginTransaction()時,會再度檢查Connection實例的AutoCommit為false,在操作過程中,最后要commit (),否則的話對數據庫的操作不會有作用,如果操作過程中因發生例外,則最后commit()不會被執行,之前的操作取消,執行rollback()可撤消之前的操作。要使用MySQL中的事務處理,必須建立事務表類型的表格例如InnoDB的表格
13.映射文件
Hibernate 中將對象與數據庫表格映射關系連接起來的是映射文件;通常以*.hbm.xml作為文件名稱;手工撰寫;通過工具程序從數據庫表格自動生成;通過工具程序從Java類自動生成三部分:類名稱與表格名稱的映射;id屬性與主鍵的映射;類屬性與表格字段的映射
1
<?xml version="1.0" encoding="utf-8"?>
2
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4
<hibernate-mapping>
5
<!--類別名稱與表格名稱映像-->
6
<class name="onlyfun.caterpillar.User" table="user">
7
<!--id與主鍵映像-->
8
<id name="id" column="id" type="java.lang.Integer">
9
<generator class="native"/>
10
</id>
11
<!--類別屬性與表格字段的映像-->
12
<property name="name" column="name" type="java.lang.String"/>
13
<property name="age" column="age" type="java.lang.Integer"/>
14
</class>
15
</hibernate-mapping>
16
注:
1.Java的數據類型與數據庫的數據類型并不是一對一對應的,為此Hibernate提供它自己的數據類型,作為Java數據類型與數
據庫數據類型的連接類型
2.<generator>設定主鍵的生成方式;“native”表示由Hibernate自動根據Dialect選擇采用 identity、hilo、sequence等作為主鍵生成方
式;可以考慮采用uuid由Hibernate根據128位UUID算法(128- bit UUID algorithm)生成16進位制數值,并編碼為32位長度的字符
串
14.基本API
1.Session-是Hibernate操作的基礎;不是設計為線程安全;一個Session由一個線程使用;
Hibernate在對數據庫進行操作之前,必須先取得Session實例,相當于JDBC在對數據庫操作之前,必須先取得Connection實例;過Session,可以對數據庫進行新增、刪除、更新;使用save()新增一條記錄;使用get()或load()方法取得id為1的記錄-User user = (User) session.get(User.class, new Integer(1));
如果未能發現相符合的記錄,則get()方法會返回null,而load()方法會丟出ObjectNotFoundException;在高級的應用中,load()方法可以返回代理對象,并可充分利用緩沖機制
Hibernate 3中,取消了find()方法,您必須通過Query或Criteria來進行記錄查詢
使用delete()刪除資料
1 User user = (User) session.get(User.class, new Integer(1));
session.delete(user);
2 Query q=session.createQuery(“delete User u where u.id=1”);
q.executeUpdate();
3 Session.delete(“from User u where u.id=1”);
使用update()方法將對象中的資料更新至對應的數據表中
Session提供了一個saveOrUpdate()方法:由定義映射文件時,設定<id>卷標的unsaved-value來決定
Session如同在編寫JDBC時需關心 Connection的管理,以有效的方法創建、利用與回收Connection,以減少資源的消耗,增加系統
執行效率一樣;SessionFactory是線程安全的(Thread-safe),然而Session則不是設計為線程安全的,所以試圖讓多個執行緒共享一個
Session,將會發生資料共享而發生混亂的問題
2.Session管理
使用了ThreadLocal類來建立一個Session管理的輔助類,這是Hibernate的Session管理一個廣為應用的解決方案
Thread-Specific Stroage模式可以有效隔離線程所使用的資源,所以避開Session的多線程之間的資源共享問題
ThreadLocal是*Thread-Specific Storage 模式*的一個運用實例
Hibernate會在真正需要數據庫操作時才(從連接池中)取得Connection
在Web應用程序中,可以藉由Filter來進行Session管理,在需要的時候開啟Session,并在Request結束之后關閉Session
3.Criteria基本查詢
Criteria對SQL進行封裝,讓開發人員可以用對象的方式來對數據庫進行操作
Criteria criteria = session.createCriteria(User.class);
// 查詢user所有字段
List<User> users = criteria.list();
Criteria實際上只是個容器,如果想要設定查詢條件,則要使用add()方法加入Restrictions的條件限制
例如查詢age大于20且小于40的資料:
1
Criteria criteria = session.createCriteria(User.class);
2
criteria.add(Restrictions.gt("age", new Integer(20)));//greater than >
3
criteria.add(Restrictions.lt("age", new Integer(40)));//lesser than <
4
List<User> users = criteria.list();
也可以使用邏輯組合來進行查詢-criteria.add(Restrictions.or(Restrictions.eq(), Restrictions.isNull())
sqlRestriction()方法來提供SQL語法作限定查詢
criteria.add(Restrictions.sqlRestriction("{alias}.name LIKE (?)", "cater%", Hibernate.STRING));//alias別名
在SQL撰寫時,不必再寫WHERE
criteria.add(Restrictions.sqlRestriction("{alias}.age BETWEEN (?) AND (?)", ages, types));
Restrictions的幾個常用限定查詢方法:eq/allEq/gt/ge/lt/le/between/like/in/and/or/sqlRestriction
4.Criteria高級查詢
使用Criteria進行查詢,并使用Order對結果進行排序
criteria.addOrder(Order.asc("age"));//desc()
setMaxResults()方法可以限定查詢回來的記錄數;setFirstResult()設定傳回查詢結果第一個記錄的位置
這兩個配合起來,就可以實現簡單的分頁
對查詢結果進行統計動作,使用Projections的avg()、rowCount()、count()、max()、min()、countDistinct()等方法
criteria.setProjection(Projections.avg("age"));
可以配合Projections的groupProperty()來對結果進行分組
criteria.setProjection(Projections.groupProperty("age"));
想結合統計與分組功能,則可以使用ProjectionList
1
ProjectionList projectionList = Projections.projectionList();
2
projectionList.add(Projections.groupProperty("age"));
3
projectionList.add(Projections.rowCount());
4
Criteria criteria = session.createCriteria(User.class);
5
criteria.setProjection(projectionList);
使用Example對象,可以將一個已知的對象作為查詢的依據
criteria.add(Example.create(user));
Criteria可以進行復合查詢
Criteria與Session綁定,其生命周期跟隨著Session結束而結束;使用Criteria時進行查詢時,每次都要于執行時期動態建立對象
能夠重復使用Criteria對象,在Hibernate 3.0中新增了DetchedCriteria對象;您可以先建立DetchedCriteria實例,并加入各種查詢條
件,并于需要查詢時再與Session綁定,獲得一個綁定Session的Criteria對象
1
// 先建立DetchedCriteria對象
2
DetachedCriteria detchedCriteria=DetachedCriteria.forClass(User.class);
3
// 加入查詢條件
4
detchedCriteria.add(Restrictions.ge("age",new Integer(25)));
5
Session session = sessionFactory.openSession();
6
// 綁定Session并返回一個Criteria實例
7
Criteria criteria = detchedCriteria.getExecutableCriteria(session);
8
5.Query接口
使用org.hibernate.Query接口的實例來進行查詢;
透過Query接口,您可以先設定查詢參數,使用setXXX()等方法,將指定的參數值填入,而不用每次都撰寫完整的HQL
在設定參數值時,必須依照 ? 所設定的順序,并使用對應類型的setXXX()方法
也可以使用命名參數(Named Parameter)
將HQL撰寫在程序之;避免硬編碼(Hard code)在程序之中,在需要修改HQL時就很方便;
在*.hbm.xml中使用<query/>卷標,并在<![CDATA[與]] >之間撰寫HQL,撰寫的位置是在</hibernate-mapping>之前
(CDATA-character data)
1
<?xml version="1.0" encoding="utf-8"?>
2
<!DOCTYPE hibernate-mapping
3
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
4
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
5
<hibernate-mapping>
6
<class name="model.User" table="user">
7
<id name="id" column="id“ type="java.lang.Integer">
8
<generator class="native"/>
9
</id>
10
<property name="name" column="name" type="java.lang.String"/>
11
<property name="age" column="age" type="java.lang.Integer"/>
12
</class>
13
<query name=“model.QueryUser">
14
<![CDATA[
15
select user.name from User as user where user.age >:minAge
16
]]>
17
</query>
18
</hibernate-mapping>
19
<query>的name屬性用來設定查詢外部HQL時的名稱依據
Query query = session.getNamedQuery(“model.QueryUser");
query.setInteger("minAge", 25);
15.HQL
1.HQL基本查詢
查詢指定類對應表格的所有記錄
Query query = session.createQuery("from User"); //也可以指定類的全稱
List names = query.list();
HQL本身不區分大小寫,不過要注意類的名稱必須區分大小寫
Hibernate會自動判定繼承關系,如果查詢的類是某類的父類,則會返回與父類、子類對應的所有表格記錄
針對某個屬性作查詢-Query query = session.createQuery("select user.name from User as user");
查詢兩個以上的屬性,查詢的結果會以數組的方式返回
Query query = session.createQuery("select user.age, user.name from User as user"); Object[] obj = (Object[]) iterator.next();
如果User類提供有適當的構建方法,則可以在使用HQL時直接指定新建一個對象傳回-
Query query = session.createQuery("select new User(user.name, user.age) from User as user");
List names = query.list();User user= (User) iterator.next(); //這個返回的User實例并未與數據庫有任何關聯
使用distinct去除資料重復的記錄-Query query = session.createQuery("select distinct user.age from User as user");
在HQL中使用函數-Query query = session.createQuery("select count(*) from User as user");
使用avg()取得屬性的平均值-Query query = session.createQuery("select avg(user.age) from User as user");
使用upper()函數將字符串轉為大寫:Query query = session.createQuery("select upper(user.name) from User as user");
2.where 子句
使用where子句來限定查詢的條件,除了 = 運算之外,還有 >、>=、<、<=、!= 或 <>等比較運算
Query query = session.createQuery("from User user where user.name=‘cjy'");
where子句上進行表達式-Query query = session.createQuery("from User user where (user.age / 10 = 3)");
在where子句上使用and、or-Query query = session.createQuery("from User user where (user.age > 20) and (user.name = ‘cjy')");
is not nullL與is null則可以測試字段值是否為空值Query query = session.createQuery("from User user where user.name is not null");
between可以測試字段值是否在指定的范圍之內-session.createQuery("from User user where user.age between 20 and 30");
使用in或not in來測試字段值是否在您指定的集合中-session.createQuery("from User user where user.name in(‘cjy', ‘abc')");
like或not like可以讓您進行模糊條件搜尋-session.createQuery("from User user where user.name like ‘c%'");
查詢結果使用order by進行排序-session.createQuery("from User user order by user.age");
可使用desc反排序-session.createQuery("from User user order by user.age desc");
同時指定兩個以上的排序方式-
session.createQuery("from User user order by user.age desc, user.name");//先按照"age"反序排,"age"相同,則按照"name"順序排列
使用GROUP BY子句,自動將指定的字段依相同的內容群組-
session.createQuery("select user.sex, avg(user.age) from User user group by user.sex");
結合having子句-session.createQuery("select user.sex, avg(user.age) from User user group by user.sex having avg(user.age) > 20");
在Hibernate 3中,HQL新增了update與delete語句,可以直接使用HQL指定更新或刪除
update子句進行更新-session.createQuery("update User set name=‘abc' where name=‘cjy'");query.executeUpdate();
delete子句進行資料刪除-session.createQuery("delete User where name=‘cjy'");query.executeUpdate();
16.SQL支持
Hibernate提供了對SQL的支持,您可以指定您所要建立的SQL,并將實體類與資料表格關聯;
// SQL,并指定別名為user
1
String sql = "select {user.*} from User user where user.age > 20";
2
Session session = sessionFactory.openSession();
3
// 建立 SQLQuery
4
SQLQuery sqlQuery = session.createSQLQuery(sql);
5
// 將別名user與實體類User關聯在一起
6
sqlQuery.addEntity("user", User.class);
7
Iterator iterator = sqlQuery.list().iterator();
8
addEntity()是將實體類與別名連結在一起的方法,大括號指定要查詢的記錄
也可以將SQL語句定義在映射文件中*.hbm.xml
<sql-query name="model.QueryUser">
<![CDATA[
select {user.*} from User user where user.age > 20
]]>
<return alias="user" class="model.User"/>
</sql-query>
Query query = session.getNamedQuery(“model.QueryUser");
Iterator iterator = query.list().iterator();
可以設定查詢參數;
<sql-query name=“model.QueryUser">
<![CDATA[
select {user.*} from User user where user.age > :age
]]>
<return alias="user" class=“model.User"/>
</sql-query>
Query query = session.getNamedQuery("model.QueryUser");
query.setInteger("age", 20);
Hibernate 3的映射文件中新增了<sql-insert>、<sql-update>與<sql-delete>三個卷標,您可以在這三個卷標中使用SQL自定義您的
INSERT、UPDATE、DELETE
1
<sql-insert>
2
INSERT INTO user (name, age) VALUES (?, ?)
3
</sql-insert>
4
<sql-update>
5
UPDATE user SET name=?, age=?, WHERE id=?
6
</sql-update>
7
<sql-delete>
8
DELETE FROM user WHERE id=?
9
</sql-delete>
? (參數) 對應的順序是映像文件中屬性出現的順序
17.映射基礎
Hibernate中的實體對象可以分為三種狀態:Transient、Persistent、Detached。
Transient-如User類所衍生出之對象,在還沒有使用save()之前都是暫存對象,這些對象還沒有與數據庫發生任何的關系,不對應于數據庫中的任一條記錄。
Persistent-當對象與數據庫中的記錄有對應關系,并且與Session實例有關聯而Session 實例尚未關閉(close),則它是在Persistent狀態;Persistent狀態的對象對應于數據庫中的一條記錄,對象的id值與記錄的主鍵值相同,并且Session實例尚未失效;在這期間您對對象的任何狀態變動,在Session實例關閉(close)或Transaction實例執行commit()之后,數據庫中對應的記錄也會跟著更新Session實例關閉(close),則Persistent狀態的對象會成為Detached狀態;使用Session的實例delete()方法刪除記錄,Persistent狀態的對象由于失去了對應的記錄,則它會成為Transient狀態。
Detached-Detached狀態的對象,其id與數據庫的主鍵值對應;Detached狀態的對象之任何屬性變動,不會對數據庫中的記錄造成任何的影響;Detached狀態的對象可以使用update()方法使之與數據庫中的對應記錄再度發生關聯,此時Detached狀態的對象會變為 Persistent狀態。
Transient與Detached狀態的對象未受Hibernate持久層管理員管理,對這兩個狀態的對象作任何屬性變動,不會對數據庫中的記錄有任何的影響;而Persistent狀態的對象受Hibernate持久層管理,對對象的屬性變動,在Session實例關閉(close)或 Transaction實例執行commit()之后,數據庫中對應的記錄也會跟著更新。在對象為Persistent時,如果對象的屬性發生變化,并且尚未提交之前,對象所攜帶的資料稱之為Dirty Data,Hibernate會在持久層
維護對象的最近讀取版本,并在資料提交時檢查兩個版本的屬性是否有變化,如果有的話,則將數據庫中的記錄進行更新。
對象識別:
要有必要比較透過查詢后兩個對象的資料是否相同(例如當對象被儲存至Set時)您必須重寫 equals()與hashCode()
重寫方法之一,equals()與hashCode()的方法是根據數據庫的identity,就是透過getId()方法取得對象的id值并加以比較
1
public class User
2
{
3
.
4
public boolean equals(Object o)
5
{
6
if(this == o) return true;
7
if(id == null || !(o instanceof User))
8
return false;
9
final User user == (User) o;
10
return this.id.equals(user.getId());
11
}
12
public int hasCode()
13
{
14
return id == null ? System.identityHashCode(this):id.hashcode();
15
}
16
}
17
上面的例子是個不被鼓勵的例子,因為當一個對象被new出來而還沒有save()時,它并不會被賦予id值,這時候就不適用這
個方法;
比較被采用的方法是根據對象中真正包括的的屬性值來作比較;
可以使用org.apache.commons.lang.builder.EqualsBuilder與 org.apache.commons.lang.builder.HashCodeBuilder來協助定義equals()與
hashCode();
Return new EqualsBuilder().append(this.name,user.getName()).append(this.phone, user.getPhone()).isEquals();
return new HashCodeBuilder().append(this.name).append(this.phone).toHashCode();
18.實體映射/集合映射/關系映射/繼承映射/緩存/鎖定/回調與攔截/工具
19.Annotation-
可以不通過*.hbm.xml,完全通過annotation搞定
hibernate.cfg.xml-
<!-- 以下設置對象與數據庫表格映像類別 -->
<mapping class="com.db.hibernate.demo.User"/>
實體標識,主鍵生成,以及相關映像,都可以使用Annotation來完成;
1
@Entity
2
@Table(name="user") // 非必要,在表格名稱與類別名稱不同時使用
3
public class User
4
{
5
@Id
6
@GeneratedValue(strategy=GenerationType.AUTO)
7
private Integer id;
8
9
@Column(name="name") // 非必要,在字段名稱與屬性名稱不同時使用
10
private String name;
11
12
@Column(name="age")
13
private Integer age; // 非必要,在字段名稱與屬性名稱不同時使用
14
15
// 必須要有一個預設的建構方法
16
// 以使得Hibernate可以使用Constructor.newInstance()建立對象
17
public User()
{ }
18
}
19
注意:import javax.persistence.*中的注解
使用Annotation時,需要的是AnnotationConfiguration類;
1
// 需要AnnotationConfiguration讀取Annotation訊息
2
Configuration config = new AnnotationConfiguration().configure();
3
// 根據 config 建立 SessionFactory
4
// SessionFactory 將用于建立 Session
5
SessionFactory sessionFactory = config.buildSessionFactory();
posted on 2011-12-26 23:11
landon 閱讀(1874)
評論(1) 編輯 收藏 所屬分類:
學習筆記