- 浏览: 548019 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (740)
- css (4)
- jquery (8)
- javascript (23)
- html (0)
- uml (0)
- 设计模式 (1)
- 开发工具 (14)
- json (4)
- struts 1.x (3)
- spring (3)
- hibernate (6)
- struts 2.x (17)
- JFreechart (0)
- j2se (48)
- jsp (9)
- flex (22)
- 找工作 (1)
- 技术杂谈 (18)
- 网络编程 (5)
- io流 (1)
- ORACLE (15)
- 报表 (3)
- extjs (11)
- jpbm (2)
- swing (5)
- jspereports (3)
- sql (1)
- linux (15)
- ps (1)
- storm (4)
- hbase (8)
- li (0)
- python (1)
- hive (3)
- 机器学习 (1)
- hdfs (1)
- elasticsearch (1)
- hadoop 2.2 (5)
- hadoop (1)
最新评论
-
Tristan_S:
这个有点意思
ASM -
starryskydog:
程序修改detail band部分的样式 如内容字体大小 ...
使用jasperReport实现动态表头 -
samwong:
Good, so usefule
使用YUI Compressor压缩CSS/JS -
gc715409742:
能够告诉我怎么在web项目中使用YUI Compressor? ...
使用YUI Compressor压缩CSS/JS -
JsonTeye:
您好! 我看你的代码,我现在也在做动态报表,实现功能由用户自己 ...
使用jasperreport动态生成pdf,excel,html
一、PO的数据类型设置
int 还是Integer Integer 允许为 null
Hibernate 既可以访问Field也可以访问Property,访问Property是只是调用getXXX()、setXXX()方法,因此在from Customer where c.name=’Tom’ HQL中,name属性不需要存在,只要getName()存在就可以了。
二、Hibernate映射
1、映射复合主键
Java代码
1. 主键类
2. Public class CustomerId implements Serializable{
3. Private final String name;
4. Private final String companyid;
5. }
6. 映射文件
7. <class name=”test.Customer” table=”CUSTOMERS”>
8. <composite-id name=”customerId” class=”test.CustomerId”>
9. <key-property name=”name” column=”NAME” type=”string”/>
10. <key-property name=”companyId” column=”COMPANY_ID” type=”long”/>
11. </composite-id>
12. <version name=”varsion” column=”VERSION” unsaved-value=”0”/>
13. <many-to-one name=”company” class=”test.Company” column=”COMPANY_ID” insert=”false” update=”false”/>
14. <set name=”orders” lazy=”true” inverse=”true”>
15. <key>
16. <column=”NAME”/>
17. <column=”COMPANY_ID”/>
18. </key>
19. </set>
20. </class>
21. <class name=”test.Order” table=”ORDERS”>
22. <many-to-one name=”customer” class=”test.Customer”>
23. <column=”NAME”/>
24. <column=”COMPANY_ID”/>
25. </many-to-one>
26. </class>
27.
28. 或
29.
30. <class name=”test.Customer” table=”CUSTOMERS”>
31. <composite-id name=”customerId” class=”test.CustomerId”>
32. <key-property name=”name” column=”NAME” type=”string”/>
33. <key-many-to-one name=”company” class=”test.Company” column=”COMPANY_ID”/>
34.
35. </composite-id>
36. <version name=”varsion” column=”VERSION” unsaved-value=”0”/>
37. <set name=”orders” lazy=”true” inverse=”true”>
38. <key>
39. <column=”NAME”/>
40. <column=”COMPANY_ID”/>
41. </key>
42. </set>
43. </class>
44. <class name=”test.Order” table=”ORDERS”>
45. <many-to-one name=”customer” class=”test.Customer”>
46. <column=”NAME”/>
47. <column=”COMPANY_ID”/>
48. </many-to-one>
49. </class>
2、映射组成关系
Java代码
1. <hibernate-mapping>
2. <class name=”Customer” table=”CUSTOMERS”>
3. <property />
4. <component name=”homeAddress” class=”Address”>
5. <parent name=”customer”/>
6. <property/>
7. </component>
8. <component name=”comAddress” class=”Address”>
9. <parent name=”customer”/>
10. <property/>
11. </component>
12. </class>
13. </hibernate-mapping>
14.
15. Public class Customer implements Serializable{
16. Address homeAddress;
17. Address comAddress;
18. }
19. Public class Address implements Serializable{//是VO不是PO不能单独Save,也不能关联。
20. Customer customer;
21. }
3、映射聚合关系
Java代码
1. <set/idbag name=”images” table=”IMAGES” lazy=”true”>
2. <key column=”CUSTOMER_ID”/>
3. <composite-element class=”Image”>
4. <parent name=”customer”/>
5. <property/>
6. <property/>
7. </composite-element>
8. </set/idbag>
9.
10. <map name=”images” table=”IMAGES” lazy=”true”>
11. <key column=”CUSTOMER_ID”/>
12. <index type=”string” column=”IMAGE_NAME”/>
13. <composite-element class=”Image”>
14. <parent name=”customer”/>
15. <property/>
16. <property/>
17. </composite-element>
18. </map >
4、映射继承关系
Java代码
1. DOClass{
2. id
3. }
4. ClassA extends DOClass{
5. A1
6. }
7.
8. ClassC extends ClassA{
9. C1
10. }
11.
12. ClassD extends ClassA{
13. D1
14. }
15.
16. ClassG extends ClassD{
17. G1
18. }
19.
20. ClassH extends ClassD{
21. H1
22. }
23.
24. ClassB extends DOClass{
25. B1
26. }
27.
28. ClassE extends ClassB{
29. E1,e2,e3,e4,e5,e6
30. }
31.
32. ClassF extends ClassB{
33. F1,f2,f3,f4,f5,f6,f7
34. }
35.
36. TABLE_A {ID(PK),A_TYPE(discriminator),A1,C1,D1,G1,H1}
37. TABLE_B {ID(PK),B1}
38. TABLE_E {B_ID(PK/FK),E1,E2,E3,E4,E5,E6}
39. TABLE_F {B_ID(PK/FK),F1,F2,F3,F4,F5,F6,F7}
40.
41. ClassA.hbm.xml
42. <hibernate-mapping>
43. <class name=”ClassA” table=”TABLE_A” discriminator-value=”A”>
44. <id/>
45. <discriminator column=”A_TYPE” type=”string”/>
46. <property name=”a1” column=”A1”/>
47. <sub-class name=”ClassC” discriminator-value=”C”>
48. <property name=”c1” column=”C1”/>
49. </sub-class>
50. <subclass name=”ClassD” discriminator-value=”D”>
51. <property name=”d1” column=”D1”/>
52. <subclass name=”ClassG” discriminator-value=”G”>
53. <property name=”g1” column=”G1”/>
54. </subclass>
55. <subclass name=”ClassH” discriminator-value=”H”>
56. <property name=”h1” column=”H1”/>
57. </subclasss>
58. </subclass>
59. </class>
60. </hibernate-mapping>
61. ClassB.hbm.xml
62. <hibernate-mapping>
63. <class name=”ClassB” table=”TABLE_B”>
64. <id/>
65. <property name=”b1” column=”B1”/>
66. <joined-subclass name=”ClassE” table=”TABLE_E”>
67. <key column=”B_ID”/>
68. <property name=”e1” column=”E1”/>
69. <property name=”e2” column=”E2”/>
70. <property name=”e3” column=”E3”/>
71. <property name=”e4” column=”E4”/>
72. <property name=”e5” column=”E5”/>
73. <property name=”e6” column=”E6”/>
74. </joined-subclass>
75. <joined-subclass name=”ClassF” table=”TABLE_F”>
76. <key column=”B_ID”/>
77. <property name=”f1” column=”F1”/>
78. <property name=”f2” column=”F2”/>
79. <property name=”f3” column=”F3”/>
80. <property name=”f4” column=”F4”/>
81. <property name=”f5” column=”F5”/>
82. <property name=”f6” column=”F6”/>
83. <property name=”f7” column=”F7”/>
84. </joined-subclass>
85. </class>
86. </hibernate-mapping>
5、映射Bag,List和Map
IDBag
Java代码
1. IMAGES{ID(PK),CUSTOMER_ID(FK),FILENAME}
2. List images = new ArrayList();
3. Customer.hbm.xml
4.
5. <idbag name=”images” table=”IMAGES” lazy=”true”>
6. <collection-id type=”long” column=”ID”>
7. <generator class=”increment”/>
8. </collection-id>
9. <key column=”CUSTOMER_ID”/>
10. <element column=”FILENAME” type=”string” not-null=”true”/>
11. </idbag>
List
Java代码
1. IMAGES{CUSTOMER_ID(PK/FK),POSITION(PK),FILENAME}
2. List images = new ArrayList();
3. Customer.hbm.xml
4. <list name=”images” table=”IMAGES” lazy=”true”>
5. <index column=”POSITION”/>
6. <key column=”CUSTOMER_ID”/>
7. <element column=”FILENAME” type=”string” not-null=”true”/>
8. </list>
Map
Java代码
1. IMAGES{CUSTOMER_ID(PK/FK),IMAGE_NAME(PK),FILENAME}
2. Map images = new HashMap();
3. <map name=”images” table=”IMAGES” lazy=”true”>
4. <key column=”CUSTOMER_ID”/>
5. <index column=”IMAGE_NAME” type=”string”/>
6. <element column=”FILENAME” type=”string” not-null=”true”/>
7. </map>
8.
9. Set idbag map 支持数据库排序 order by =”ID”
10. Set map 支持内存排序 sort = “MyComparator”
6、映射一对一关联关系特殊情况一
Java代码
1. Public class Customer{
2. Address homeAddress;
3. Address comAddress;
4. }
5.
6. Customer.hbm.xml
7. <many-to-one name=”homeAddress” class=”Address” column=”HOME_ADDRESS_ID” cascade=”all” unique=”true”/>
8. <many-to-one name=”comAddress” class=”Address” column=”COM_ADDRESS_ID” cascade=”all” unique=”true”/>
9.
10. Address.hbm.xml
11. <one-to-one name=”address” class=”Customer” property-ref=”homeAddress”/>
映射一对一关联关系主键映射
Java代码
1. Customer.hbm.xml
2. <one-to-one name=”address” class=”Address” cascade=”all”/>
3. Address.hbm.xml
4. <class name=”address”>
5. <id>
6. <generator class=”foreign”>
7. <param name=”property”>customer</param>
8. </generator>
9. </id>
10. <one-to-one name=”customer” class=”Customer” constrained=”true”/>
11. </class>
7、映射一对多关联
Java代码
1. <class name="Person">
2. <id name="id" column="personId">
3. <generator class="native"/>
4. </id>
5. <many-to-one name="address" column="addressId" not-null="true"/>
6. </class>
7.
8. <class name="Address">
9. <id name="id" column="addressId">
10. <generator class="native"/>
11. </id>
12. <set name="people" inverse="true">
13. <key column="addressId"/>
14. <one-to-many class="Person"/>
15. </set>
16. </class>
8、映射多对多关联
Java代码
1. <set name=”items” table=”CATEGORY_ITEM” lazy=”true” cascade=”save-update”>
2. <key column=”CATEGORY_ID”>
3. <many-to-many class=”Item” column=”ITEM_ID”/>
4. </set>
三、Inverse与cascade
Inverse
应该将Set的inverse属性设置为true,如果为many-to-many 需要将一方设置为true
如Customer:Order为1:N双向关联,将Customer的Set的inverse设置为true,表示Customer与Order之间的关联关系由Order端来维护,如customer.getOrders().addOrder(o)不会更新Customer与Order之间的关联关系,而order.setCustomer(o)才会更新Customer与Order之间的关联关系。
Cascade
Save-update 保存、更新Customer会同步更新Order.
Delete 同步删除
All 包含save-update和delete操作,另外调用当前对象的evice或者lock时,对关联对象也调用相应方法。
Delete-orphan 删除所有和当前对象解除关联关系的对象。
All-delete-orphan 当关联双方为父子关系是(父亲控制孩子的持久化生命周期),如果父方删除,子方自动删除(同delete),如果子方无父亲,子方应删除。包含Delete和all-orphan的行为。
四、Hibernate缓存
Session 缓存(一级缓存),每一session确保自己的缓存的所有的持久对象唯一
通过调用session.setFlushMode()可设定缓存的清理模式,缓存的清理模式有三种:
FlushMode.AUTO:query、commit和flush的时候清理缓存。
FlushMode.COMMIT:commit和flush的时候清理缓存。
FlushMode.NEVER:只有在调用session.flush()的时候才清理缓存。
Session 只有在清理缓存的时候才会执行相应的sql操作。
可以使用session.evict()和session.clear()清空缓存。
Save、update、query都加入Session缓存
Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c 除外。
SessionFactory缓存(二级缓存)
Java代码
1. <class name=”Category” table=”CATEGORYS”>
2. <cache usage=”read-write”/>
3. <id/>
4. <set name=”items” inverse=”true” lazy=”true”>
5. <cache usage=”read-write”/>
6. <key…/>
7. </set>
8. </class>
9. <class name=”Item”>
10. <cache usage=”read-write”/>
11. <id/>
12. </class>
13.
14. Hibernate.cache.provider=…………EhCacheProvider
15. Hibernate.cache.user_query_cache=true
16.
17. Ehcache.xml
18. <ehcache>
19. <diskStore path=”c:\\temp”/>
20. <defaultCache
21. maxElementsInMemory=”10000”
22. eternal=”false”
23. timeToIdleSeconds=”120”
24. timeToLiveSeconds=”120”
25. overflowToDisk=”true”/>
26. <cache name=”Category”
27. maxElementsInMemory=”10000”
28. eternal=”false”
29. timeToIdleSeconds=”120”
30. timeToLiveSeconds=”120”
31. overflowToDisk=”true”/>
32.
33. <cache name=”Category.Items”
34. maxElementsInMemory=”10000”
35. eternal=”false”
36. timeToIdleSeconds=”120”
37. timeToLiveSeconds=”120”
38. overflowToDisk=”true”/>
39.
40. <cache name=”Item”
41. maxElementsInMemory=”10000”
42. eternal=”false”
43. timeToIdleSeconds=”120”
44. timeToLiveSeconds=”120”
45. overflowToDisk=”true”/>
46.
47. <cache name=”customerQueries”…./> <!—设置查询缓存
48.
49. </ehcache>
Query q = session.createQuery();
q.setCacheable(true);
q.setCacheRegion(“customerQueries”);
SessionFactory.evict(),SessionFactory.evictCollection()清除二级缓存。
直接调用JDBC API不会使用任何缓存。
二级缓存适合查询较多但是很少更新的情况。
尽量对数据库的所有操作由Hibernate来完成,而不要用其它方式对数据库进行操作,否则可能与缓存冲突,当然如果对缓存有深入研究的除外。
五、临时对象(Transient Object)、持久对象(Persistent Object)和游离对象(Detached Object)
临时对象:表示对象的主键不存在(OID不存在),Hibernate通过key的unsave-value或者version的unsaved-value来判断是否为临时对象。Session对临时对象的唯一操作应该是save()。
持久对象:在session缓存中存在持久对象,数据库中存在相应纪录。
游离对象:数据库中有相应纪录,session中不存在持久对象,可通过session.evict()获得。
Session缓存中存在,数据库中不存在,这是什么类型的对象?实际这种情况不存在,因为所有的Session操作均在事务中进行,缓存中的数据是通过save、update或者query生成,而save或者update得到的是数据库的独占锁,因此其它事务没有可能删除数据库中的数据。而query获得的是数据库的共享锁,因此其它事务也不可能获得独占锁来更新数据。因此在一个事务内部session缓存才有意义,如果脱离事务,仅仅是只读操作也可能导致session缓存中存在数据库中根本不存在相应纪录的持久性对象。
六、Hibernate 的检索策略
设定批量检索数量 batch-size
外连接深度控制hibernate.max_fetch_depth
类级别检索 load、get和find。其中load可以设置延迟检索(cglib生成代理类,可通过Hibernate.initialize()初始化),这也是load和get的区别之一。Get/find立即检索,与是否设置延迟无关。
关联检索 立即检索,延迟检索,迫切左外连接检索。Set/list/map等,无论是否延迟检索得到的都是代理集合类。而非HashSet,ArrayList等。
Lazy与outer-joint
False,false 立即检索
False,true 迫切左外连接,
True,false 延迟检索
Many-to-one 的outer-join属性
Auto:Customer的lazy为true则延迟加载,否则迫切左外连接
True:迫切左外连接
False:延迟加载或者立即加载由Customer的lazy决定。
One-to-one的延迟加载策略
<one-to-one name=”customer” class=”Customer” constrained=”true”/>
HQL会忽略迫切左外连接检索和lazy(只有load才为代理对象)策略。
Session.find(“from Customer c as c left join fetch c.orders where c.id=1”)
Hibernate的检索方式
HQL、NativeSql和QBC
From Customer c inner join c.orders o 查询结果保存到session缓存
Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c查询结果不存入Session缓存。
七、Hibernate并发控制
乐观锁:VERSION或者timestamp控制,session.lock()立刻进行版本检查,session.update(),update的时候执行版本检查。
悲观锁:select for upload,session.get(Customer.class,new Long(1),LockMode.UPGRADE)
总结:本文绝大多数为摘录内容,有些地方加上自己的理解,有不对之处恳请批评指正。看了书,阅读了相关帖子后,感觉学习Hibernate的重点应该是Hibernate的缓存策、查询和如何提高性能方面。
另外说点自己的感受,本人做项目到现在都是在设计阶段先有关系模型后有对象模型(其实一个Table一个对象),在这种情况下Hibernate的优势大大降低了,其实是为了Hibernate而Hibernate了,个人感觉在先有关系模型的情况下用Hibernate的意义不大。
如果按照OOAD的开发流程先有对象模型,然后根据对象模型生成关系模型,那应该说用Hibernate用对了地方。毕竟Hibernate对继承、多态,各种复杂的关系都有很好的支持。
int 还是Integer Integer 允许为 null
Hibernate 既可以访问Field也可以访问Property,访问Property是只是调用getXXX()、setXXX()方法,因此在from Customer where c.name=’Tom’ HQL中,name属性不需要存在,只要getName()存在就可以了。
二、Hibernate映射
1、映射复合主键
Java代码
1. 主键类
2. Public class CustomerId implements Serializable{
3. Private final String name;
4. Private final String companyid;
5. }
6. 映射文件
7. <class name=”test.Customer” table=”CUSTOMERS”>
8. <composite-id name=”customerId” class=”test.CustomerId”>
9. <key-property name=”name” column=”NAME” type=”string”/>
10. <key-property name=”companyId” column=”COMPANY_ID” type=”long”/>
11. </composite-id>
12. <version name=”varsion” column=”VERSION” unsaved-value=”0”/>
13. <many-to-one name=”company” class=”test.Company” column=”COMPANY_ID” insert=”false” update=”false”/>
14. <set name=”orders” lazy=”true” inverse=”true”>
15. <key>
16. <column=”NAME”/>
17. <column=”COMPANY_ID”/>
18. </key>
19. </set>
20. </class>
21. <class name=”test.Order” table=”ORDERS”>
22. <many-to-one name=”customer” class=”test.Customer”>
23. <column=”NAME”/>
24. <column=”COMPANY_ID”/>
25. </many-to-one>
26. </class>
27.
28. 或
29.
30. <class name=”test.Customer” table=”CUSTOMERS”>
31. <composite-id name=”customerId” class=”test.CustomerId”>
32. <key-property name=”name” column=”NAME” type=”string”/>
33. <key-many-to-one name=”company” class=”test.Company” column=”COMPANY_ID”/>
34.
35. </composite-id>
36. <version name=”varsion” column=”VERSION” unsaved-value=”0”/>
37. <set name=”orders” lazy=”true” inverse=”true”>
38. <key>
39. <column=”NAME”/>
40. <column=”COMPANY_ID”/>
41. </key>
42. </set>
43. </class>
44. <class name=”test.Order” table=”ORDERS”>
45. <many-to-one name=”customer” class=”test.Customer”>
46. <column=”NAME”/>
47. <column=”COMPANY_ID”/>
48. </many-to-one>
49. </class>
2、映射组成关系
Java代码
1. <hibernate-mapping>
2. <class name=”Customer” table=”CUSTOMERS”>
3. <property />
4. <component name=”homeAddress” class=”Address”>
5. <parent name=”customer”/>
6. <property/>
7. </component>
8. <component name=”comAddress” class=”Address”>
9. <parent name=”customer”/>
10. <property/>
11. </component>
12. </class>
13. </hibernate-mapping>
14.
15. Public class Customer implements Serializable{
16. Address homeAddress;
17. Address comAddress;
18. }
19. Public class Address implements Serializable{//是VO不是PO不能单独Save,也不能关联。
20. Customer customer;
21. }
3、映射聚合关系
Java代码
1. <set/idbag name=”images” table=”IMAGES” lazy=”true”>
2. <key column=”CUSTOMER_ID”/>
3. <composite-element class=”Image”>
4. <parent name=”customer”/>
5. <property/>
6. <property/>
7. </composite-element>
8. </set/idbag>
9.
10. <map name=”images” table=”IMAGES” lazy=”true”>
11. <key column=”CUSTOMER_ID”/>
12. <index type=”string” column=”IMAGE_NAME”/>
13. <composite-element class=”Image”>
14. <parent name=”customer”/>
15. <property/>
16. <property/>
17. </composite-element>
18. </map >
4、映射继承关系
Java代码
1. DOClass{
2. id
3. }
4. ClassA extends DOClass{
5. A1
6. }
7.
8. ClassC extends ClassA{
9. C1
10. }
11.
12. ClassD extends ClassA{
13. D1
14. }
15.
16. ClassG extends ClassD{
17. G1
18. }
19.
20. ClassH extends ClassD{
21. H1
22. }
23.
24. ClassB extends DOClass{
25. B1
26. }
27.
28. ClassE extends ClassB{
29. E1,e2,e3,e4,e5,e6
30. }
31.
32. ClassF extends ClassB{
33. F1,f2,f3,f4,f5,f6,f7
34. }
35.
36. TABLE_A {ID(PK),A_TYPE(discriminator),A1,C1,D1,G1,H1}
37. TABLE_B {ID(PK),B1}
38. TABLE_E {B_ID(PK/FK),E1,E2,E3,E4,E5,E6}
39. TABLE_F {B_ID(PK/FK),F1,F2,F3,F4,F5,F6,F7}
40.
41. ClassA.hbm.xml
42. <hibernate-mapping>
43. <class name=”ClassA” table=”TABLE_A” discriminator-value=”A”>
44. <id/>
45. <discriminator column=”A_TYPE” type=”string”/>
46. <property name=”a1” column=”A1”/>
47. <sub-class name=”ClassC” discriminator-value=”C”>
48. <property name=”c1” column=”C1”/>
49. </sub-class>
50. <subclass name=”ClassD” discriminator-value=”D”>
51. <property name=”d1” column=”D1”/>
52. <subclass name=”ClassG” discriminator-value=”G”>
53. <property name=”g1” column=”G1”/>
54. </subclass>
55. <subclass name=”ClassH” discriminator-value=”H”>
56. <property name=”h1” column=”H1”/>
57. </subclasss>
58. </subclass>
59. </class>
60. </hibernate-mapping>
61. ClassB.hbm.xml
62. <hibernate-mapping>
63. <class name=”ClassB” table=”TABLE_B”>
64. <id/>
65. <property name=”b1” column=”B1”/>
66. <joined-subclass name=”ClassE” table=”TABLE_E”>
67. <key column=”B_ID”/>
68. <property name=”e1” column=”E1”/>
69. <property name=”e2” column=”E2”/>
70. <property name=”e3” column=”E3”/>
71. <property name=”e4” column=”E4”/>
72. <property name=”e5” column=”E5”/>
73. <property name=”e6” column=”E6”/>
74. </joined-subclass>
75. <joined-subclass name=”ClassF” table=”TABLE_F”>
76. <key column=”B_ID”/>
77. <property name=”f1” column=”F1”/>
78. <property name=”f2” column=”F2”/>
79. <property name=”f3” column=”F3”/>
80. <property name=”f4” column=”F4”/>
81. <property name=”f5” column=”F5”/>
82. <property name=”f6” column=”F6”/>
83. <property name=”f7” column=”F7”/>
84. </joined-subclass>
85. </class>
86. </hibernate-mapping>
5、映射Bag,List和Map
IDBag
Java代码
1. IMAGES{ID(PK),CUSTOMER_ID(FK),FILENAME}
2. List images = new ArrayList();
3. Customer.hbm.xml
4.
5. <idbag name=”images” table=”IMAGES” lazy=”true”>
6. <collection-id type=”long” column=”ID”>
7. <generator class=”increment”/>
8. </collection-id>
9. <key column=”CUSTOMER_ID”/>
10. <element column=”FILENAME” type=”string” not-null=”true”/>
11. </idbag>
List
Java代码
1. IMAGES{CUSTOMER_ID(PK/FK),POSITION(PK),FILENAME}
2. List images = new ArrayList();
3. Customer.hbm.xml
4. <list name=”images” table=”IMAGES” lazy=”true”>
5. <index column=”POSITION”/>
6. <key column=”CUSTOMER_ID”/>
7. <element column=”FILENAME” type=”string” not-null=”true”/>
8. </list>
Map
Java代码
1. IMAGES{CUSTOMER_ID(PK/FK),IMAGE_NAME(PK),FILENAME}
2. Map images = new HashMap();
3. <map name=”images” table=”IMAGES” lazy=”true”>
4. <key column=”CUSTOMER_ID”/>
5. <index column=”IMAGE_NAME” type=”string”/>
6. <element column=”FILENAME” type=”string” not-null=”true”/>
7. </map>
8.
9. Set idbag map 支持数据库排序 order by =”ID”
10. Set map 支持内存排序 sort = “MyComparator”
6、映射一对一关联关系特殊情况一
Java代码
1. Public class Customer{
2. Address homeAddress;
3. Address comAddress;
4. }
5.
6. Customer.hbm.xml
7. <many-to-one name=”homeAddress” class=”Address” column=”HOME_ADDRESS_ID” cascade=”all” unique=”true”/>
8. <many-to-one name=”comAddress” class=”Address” column=”COM_ADDRESS_ID” cascade=”all” unique=”true”/>
9.
10. Address.hbm.xml
11. <one-to-one name=”address” class=”Customer” property-ref=”homeAddress”/>
映射一对一关联关系主键映射
Java代码
1. Customer.hbm.xml
2. <one-to-one name=”address” class=”Address” cascade=”all”/>
3. Address.hbm.xml
4. <class name=”address”>
5. <id>
6. <generator class=”foreign”>
7. <param name=”property”>customer</param>
8. </generator>
9. </id>
10. <one-to-one name=”customer” class=”Customer” constrained=”true”/>
11. </class>
7、映射一对多关联
Java代码
1. <class name="Person">
2. <id name="id" column="personId">
3. <generator class="native"/>
4. </id>
5. <many-to-one name="address" column="addressId" not-null="true"/>
6. </class>
7.
8. <class name="Address">
9. <id name="id" column="addressId">
10. <generator class="native"/>
11. </id>
12. <set name="people" inverse="true">
13. <key column="addressId"/>
14. <one-to-many class="Person"/>
15. </set>
16. </class>
8、映射多对多关联
Java代码
1. <set name=”items” table=”CATEGORY_ITEM” lazy=”true” cascade=”save-update”>
2. <key column=”CATEGORY_ID”>
3. <many-to-many class=”Item” column=”ITEM_ID”/>
4. </set>
三、Inverse与cascade
Inverse
应该将Set的inverse属性设置为true,如果为many-to-many 需要将一方设置为true
如Customer:Order为1:N双向关联,将Customer的Set的inverse设置为true,表示Customer与Order之间的关联关系由Order端来维护,如customer.getOrders().addOrder(o)不会更新Customer与Order之间的关联关系,而order.setCustomer(o)才会更新Customer与Order之间的关联关系。
Cascade
Save-update 保存、更新Customer会同步更新Order.
Delete 同步删除
All 包含save-update和delete操作,另外调用当前对象的evice或者lock时,对关联对象也调用相应方法。
Delete-orphan 删除所有和当前对象解除关联关系的对象。
All-delete-orphan 当关联双方为父子关系是(父亲控制孩子的持久化生命周期),如果父方删除,子方自动删除(同delete),如果子方无父亲,子方应删除。包含Delete和all-orphan的行为。
四、Hibernate缓存
Session 缓存(一级缓存),每一session确保自己的缓存的所有的持久对象唯一
通过调用session.setFlushMode()可设定缓存的清理模式,缓存的清理模式有三种:
FlushMode.AUTO:query、commit和flush的时候清理缓存。
FlushMode.COMMIT:commit和flush的时候清理缓存。
FlushMode.NEVER:只有在调用session.flush()的时候才清理缓存。
Session 只有在清理缓存的时候才会执行相应的sql操作。
可以使用session.evict()和session.clear()清空缓存。
Save、update、query都加入Session缓存
Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c 除外。
SessionFactory缓存(二级缓存)
Java代码
1. <class name=”Category” table=”CATEGORYS”>
2. <cache usage=”read-write”/>
3. <id/>
4. <set name=”items” inverse=”true” lazy=”true”>
5. <cache usage=”read-write”/>
6. <key…/>
7. </set>
8. </class>
9. <class name=”Item”>
10. <cache usage=”read-write”/>
11. <id/>
12. </class>
13.
14. Hibernate.cache.provider=…………EhCacheProvider
15. Hibernate.cache.user_query_cache=true
16.
17. Ehcache.xml
18. <ehcache>
19. <diskStore path=”c:\\temp”/>
20. <defaultCache
21. maxElementsInMemory=”10000”
22. eternal=”false”
23. timeToIdleSeconds=”120”
24. timeToLiveSeconds=”120”
25. overflowToDisk=”true”/>
26. <cache name=”Category”
27. maxElementsInMemory=”10000”
28. eternal=”false”
29. timeToIdleSeconds=”120”
30. timeToLiveSeconds=”120”
31. overflowToDisk=”true”/>
32.
33. <cache name=”Category.Items”
34. maxElementsInMemory=”10000”
35. eternal=”false”
36. timeToIdleSeconds=”120”
37. timeToLiveSeconds=”120”
38. overflowToDisk=”true”/>
39.
40. <cache name=”Item”
41. maxElementsInMemory=”10000”
42. eternal=”false”
43. timeToIdleSeconds=”120”
44. timeToLiveSeconds=”120”
45. overflowToDisk=”true”/>
46.
47. <cache name=”customerQueries”…./> <!—设置查询缓存
48.
49. </ehcache>
Query q = session.createQuery();
q.setCacheable(true);
q.setCacheRegion(“customerQueries”);
SessionFactory.evict(),SessionFactory.evictCollection()清除二级缓存。
直接调用JDBC API不会使用任何缓存。
二级缓存适合查询较多但是很少更新的情况。
尽量对数据库的所有操作由Hibernate来完成,而不要用其它方式对数据库进行操作,否则可能与缓存冲突,当然如果对缓存有深入研究的除外。
五、临时对象(Transient Object)、持久对象(Persistent Object)和游离对象(Detached Object)
临时对象:表示对象的主键不存在(OID不存在),Hibernate通过key的unsave-value或者version的unsaved-value来判断是否为临时对象。Session对临时对象的唯一操作应该是save()。
持久对象:在session缓存中存在持久对象,数据库中存在相应纪录。
游离对象:数据库中有相应纪录,session中不存在持久对象,可通过session.evict()获得。
Session缓存中存在,数据库中不存在,这是什么类型的对象?实际这种情况不存在,因为所有的Session操作均在事务中进行,缓存中的数据是通过save、update或者query生成,而save或者update得到的是数据库的独占锁,因此其它事务没有可能删除数据库中的数据。而query获得的是数据库的共享锁,因此其它事务也不可能获得独占锁来更新数据。因此在一个事务内部session缓存才有意义,如果脱离事务,仅仅是只读操作也可能导致session缓存中存在数据库中根本不存在相应纪录的持久性对象。
六、Hibernate 的检索策略
设定批量检索数量 batch-size
外连接深度控制hibernate.max_fetch_depth
类级别检索 load、get和find。其中load可以设置延迟检索(cglib生成代理类,可通过Hibernate.initialize()初始化),这也是load和get的区别之一。Get/find立即检索,与是否设置延迟无关。
关联检索 立即检索,延迟检索,迫切左外连接检索。Set/list/map等,无论是否延迟检索得到的都是代理集合类。而非HashSet,ArrayList等。
Lazy与outer-joint
False,false 立即检索
False,true 迫切左外连接,
True,false 延迟检索
Many-to-one 的outer-join属性
Auto:Customer的lazy为true则延迟加载,否则迫切左外连接
True:迫切左外连接
False:延迟加载或者立即加载由Customer的lazy决定。
One-to-one的延迟加载策略
<one-to-one name=”customer” class=”Customer” constrained=”true”/>
HQL会忽略迫切左外连接检索和lazy(只有load才为代理对象)策略。
Session.find(“from Customer c as c left join fetch c.orders where c.id=1”)
Hibernate的检索方式
HQL、NativeSql和QBC
From Customer c inner join c.orders o 查询结果保存到session缓存
Select c.ID,c.Name,c.age,o.ORDER_NUM,o.CUSTOMER_ID from Customer c,inner join c.orders c查询结果不存入Session缓存。
七、Hibernate并发控制
乐观锁:VERSION或者timestamp控制,session.lock()立刻进行版本检查,session.update(),update的时候执行版本检查。
悲观锁:select for upload,session.get(Customer.class,new Long(1),LockMode.UPGRADE)
总结:本文绝大多数为摘录内容,有些地方加上自己的理解,有不对之处恳请批评指正。看了书,阅读了相关帖子后,感觉学习Hibernate的重点应该是Hibernate的缓存策、查询和如何提高性能方面。
另外说点自己的感受,本人做项目到现在都是在设计阶段先有关系模型后有对象模型(其实一个Table一个对象),在这种情况下Hibernate的优势大大降低了,其实是为了Hibernate而Hibernate了,个人感觉在先有关系模型的情况下用Hibernate的意义不大。
如果按照OOAD的开发流程先有对象模型,然后根据对象模型生成关系模型,那应该说用Hibernate用对了地方。毕竟Hibernate对继承、多态,各种复杂的关系都有很好的支持。
发表评论
-
关于hibernate不能自动创建表的问题
2010-09-26 22:43 2975hibernate不能自动生成表原因分析及解决办法 2010 ... -
Hibernate generator小结
2010-09-20 16:58 909Hibernate generator小结 Xm ... -
hibernate包详解
2010-09-03 11:40 9071.Hibernate3.jar 编译hibernate所 ... -
Hibernate常见错误
2010-07-24 19:50 1733Hibernate常见错误 Hibernate常见错误 1.错 ... -
hibernate笔记
2010-07-24 19:43 912部门代码 Department.java: package c ...
相关推荐
Hibernate分页查询小结
### Hibernate学习笔记小结 #### 一、简介与配置 **Hibernate** 是一款开源的对象关系映射(ORM)框架,它允许开发人员将Java对象自动持久化到数据库表中,从而简化了数据访问层的开发工作。在Spring框架中,...
### Hibernate框架技术总结 #### 一、概述 Hibernate是一个开源的对象关系映射(ORM)框架,它为Java应用提供了一种高效、灵活的方式来处理数据库交互。通过Hibernate,开发者可以使用面向对象的方式操作数据库,...
NULL 博文链接:https://tcrct.iteye.com/blog/243252
在Java世界中,尤其是在持久化框架Hibernate中,处理Clob类型的数据需要特别的方法和配置。 在Hibernate中,Clob类型的字段通常有两种处理方式: 1. **传统JDBC方式**: 在这种模式下,开发者需要直接操作Clob...
Hibernate是一个开源的Java框架,它为对象关系映射(Object Relational Mapping, ORM)提供了一种实现方式,允许Java程序员以面向对象的方式操作数据库。从Hibernate的核心概念、工作原理到其实现细节,Hibernate...
这篇博客文章“Hibernate操作Oracle中Clob、Blob字段小结”可能会探讨如何在Hibernate中有效地处理这两种类型的数据。 1. **Clob与Blob的理解**: - Clob:Clob是用于存储大量字符数据的类型,例如长篇文章、XML...
【MAPPING Hibernate方法小结】 Hibernate 是一个流行的Java ORM(对象关系映射)框架,它允许开发者用面向对象的方式操作数据库。以下是对Hibernate中几种关键概念的详细解释: 1. **对象之间的关系**: - **...
在Hibernate框架中,Clob类型的字段处理是数据库操作中的一个关键环节,尤其是在处理大量文本数据时。以下是对Oracle Clob在Hibernate中应用的详细总结: 3.1 传统的JDBC方式: 在没有使用ORM框架之前,我们通常...
在构建企业级应用时,常常会采用Struts2、Hibernate和Spring这三种技术进行整合,形成SSH框架。这里我们主要讨论SSH项目中的Hibernate部分,它是一个强大的对象关系映射(ORM)框架,使得开发者可以方便地将数据库...
关于Clob类型在Hibernate中的应用小结.doc
hibernate 映射关系 小结
1.3 小结 1.4 思考题 第2章 Java对象持久化技术概述 2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 ...
1.5 小结 第2章 启动项目 2.1 启动Hibernate项目 2.1.1 选择开发过程 2.1.2 建立项目 2.1.3 Hibernate配置和启动 2.1.4 运行和测试应用程序 2.2 启动Java Persistence项目 2.2.1 ...
"educationSelectItemInfos" executeResult="false" /> ...在实际项目中,还需要结合Hibernate进行持久层操作,以及Spring进行依赖注入和事务管理,共同构建出完整的SSH(Struts2 + Hibernate + Spring)企业级应用。