前言:

  最近正在学习Hibernate通过注解(annotation)来管理映射关系,以前都是通过XML映射文件。下面拿个小例子说一下。

数据库物理模型:

数据库的描述:

  一篇博客随笔可以分到不同的类中,一个类中又可以包含许多不同的博客随笔。就如同博客园的设计。也就是上图中 博客-组 和 博客-消息是多对多的映射。

Hibernate关联映射方式:

  双向N-N关联, 两端都要使用Set集合属性,两端都增加对集合属性的访问。双向N-N关联没有太多的选择,只能采用连接表来建立两个实体之间的关联关系。

生成sql语句:

  1. drop table if exists blogGroup;
  2.  
  3. drop table if exists blogMessage;
  4.  
  5. drop table if exists groupMessage;
  6.  
  7. create table blogGroup
  8. (
  9. groupId int not null auto_increment,
  10. groupName varchar(50),
  11. primary key (groupId)
  12. );
  13.  
  14. create table blogMessage
  15. (
  16. msgId int not null auto_increment,
  17. msgContent varchar(1000),
  18. primary key (msgId)
  19. );
  20.  
  21. create table groupMessage
  22. (
  23. groupId int not null,
  24. msgId int not null,
  25. primary key (groupId, msgId)
  26. );
  27.  
  28. alter table groupMessage add constraint FK_Relationship_1 foreign key (groupId)
  29. references blogGroup (groupId) on delete restrict on update restrict;
  30.  
  31. alter table groupMessage add constraint FK_Relationship_2 foreign key (msgId)
  32. references blogMessage (msgId) on delete restrict on update restrict;

PO(persisent object)类:

  PO = POJO(plain ordinary java object) + 注解

PO : BlogGroup

  1. package com.blog.entriy;
  2.  
  3. @Entity
  4. @Table(name="blogGroup")
  5. public class BlogGroup implements Serializable{
  6. @Id
  7. @Column(name="groupId")
  8. @GeneratedValue(strategy=GenerationType.IDENTITY)
  9. private int groupId;
  10. @Column(name="groupName")
  11. private String groupName;
  12.  
  13. //fetch=FetchType.EAGER 抓取实体时,立即抓取关联实体,我用的get()方式加载一个对象
  14. //ascadeType.PERSIST, CascadeType.MERGE, 分别是更新和保存时级联
  15. @ManyToMany(targetEntity=BlogMessage.class, cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
  16. @JoinTable(name="groupMessage",
  17. joinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId"),
  18. inverseJoinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId")
  19. )
  20. private Set<BlogMessage> message = new HashSet<BlogMessage>();
  21.  
  22. public int getGroupId() {
  23. return groupId;
  24. }
  25. public void setGroupId(int groupId) {
  26. this.groupId = groupId;
  27. }
  28. public String getGroupName() {
  29. return groupName;
  30. }
  31. public void setGroupName(String groupName) {
  32. this.groupName = groupName;
  33. }
  34. public Set<BlogMessage> getMessage() {
  35. return message;
  36. }
  37. public void setMessage(Set<BlogMessage> message) {
  38. this.message = message;
  39. }
  40. }

PO : BlogMessage

  1. package com.blog.entriy;
  2.  
  3. @Entity
  4. @Table(name="blogMessage")
  5. public class BlogMessage implements Serializable{
  6. @Id
  7. @Column(name="msgId")
  8. @GeneratedValue(strategy=GenerationType.IDENTITY)
  9. private int msgId;
  10. @Column(name="msgContent")
  11. private String msgContent;
  12.  
  13. @ManyToMany(targetEntity=BlogGroup.class)
  14. @JoinTable(name="groupMessage",
  15. joinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId"),
  16. inverseJoinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId")
  17. )
  18. private Set<BlogGroup> group = new HashSet<BlogGroup>();
  19.  
  20. public int getMsgId() {
  21. return msgId;
  22. }
  23.  
  24. public void setMsgId(int msgId) {
  25. this.msgId = msgId;
  26. }
  27. public String getMsgContent() {
  28. return msgContent;
  29. }
  30. public void setMsgContent(String msgContent) {
  31. this.msgContent = msgContent;
  32. }
  33. public Set<BlogGroup> getGroup() {
  34. return group;
  35. }
  36. public void setGroup(Set<BlogGroup> group) {
  37. this.group = group;
  38. }
  39. }

Hibernate中数据的三种状态

  补充一下:Dao层的操作,需要掌握Hibernate中数据的三种状态

  1,  临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

  2,  持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

  3,  游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。

  

盗图两张

  1.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是瞬时对象(Transient)。

  2.瞬时对象调用save方法,或者离线对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句。

  3.离线对象就是,数据库存在该对象,但是该对象又没有被session所托管。

DAO层:

  分别测试了不同方式的插入操作, 以及更新和删除。具体看函数的实现。

  1. package com.blog.dao;
  2.  
  3. public class BlogDao {
  4. private SessionFactory sessionFactory;
  5.  
  6. public Session getSession() {
  7. return sessionFactory.getCurrentSession();
  8. }
  9.  
  10. public SessionFactory getSessionFactory() {
  11. return sessionFactory;
  12. }
  13.  
  14. public void setSessionFactory(SessionFactory sessionFactory) {
  15. this.sessionFactory = sessionFactory;
  16. }
  17.  
  18. public BlogGroup get_test(int id){
  19. BlogGroup blogGroup = null;
  20. Session session = null;
  21. Transaction tran = null;
  22. try{
  23. session = this.getSession();
  24. tran = session.beginTransaction();
  25. blogGroup = (BlogGroup)session.get(BlogGroup.class, id);
  26. tran.commit();
  27. } catch(Exception e){
  28. System.out.println(e.toString());
  29. tran.rollback();
  30. }
  31. return blogGroup;
  32. }

  33.   //只插入一端博客-组(BlogGroup)
  34. public void insert_test1(){
  35. Session session = null;
  36. Transaction tran = null;
  37. try{
  38. session = this.getSession();
  39. tran = session.beginTransaction();
  40. BlogGroup blogGroup = new BlogGroup();
  41. blogGroup.setGroupName("html");
  42. session.save(blogGroup);
  43. tran.commit();
  44. } catch(Exception e){
  45. System.out.println(e.toString());
  46. tran.rollback();
  47. }
  48. }
  49. //同时插入两端(博客-组 和 博客-消息),没有用cascade级联操作,所以BlogGroup和BlogMessage两端都要先持久化
  50. public void insert_test2(){
  51. Session session = null;
  52. Transaction tran = null;
  53. try{
  54. session = this.getSession();
  55. tran = session.beginTransaction();
  56. BlogGroup blogGroup = new BlogGroup();
  57. blogGroup.setGroupName("c++");
  58. BlogMessage blogMessage = new BlogMessage();
  59. blogMessage.setMsgContent("c++ primer");
  60. session.save(blogMessage);
  61. Set<BlogMessage> message = new HashSet<BlogMessage>();
  62. message.add(blogMessage);
  63. blogGroup.setMessage(message);
  64. session.save(blogGroup);
  65. tran.commit();
  66. } catch(Exception e){
  67. System.out.println(e.toString());
  68. tran.rollback();
  69. }
  70. }
  71. //同时插入两端,对BlogGroup设置persist级联操作 @ManyToMany(cascade={CascadeType.PERSIST})
  72. public void insert_test3(){
  73. Session session = null;
  74. Transaction tran = null;
  75. try{
  76. session = this.getSession();
  77. tran = session.beginTransaction();
  78. BlogGroup blogGroup = new BlogGroup();
  79. blogGroup.setGroupName("javaee");
  80. BlogMessage blogMessage = new BlogMessage();
  81. blogMessage.setMsgContent("Spring+hibernate+struct");
  82. blogGroup.getMessage().add(blogMessage);
  83. session.persist(blogGroup);
  84. tran.commit();
  85. } catch(Exception e){
  86. System.out.println(e.toString());
  87. tran.rollback();
  88. }
  89. }
  90. //向博客-组(BlogGroup)添加新的 博客-消息(BlogMessage),对BlogGroup再添加一个更新的级联操作,CascadeType.MERGE
  91. public void update_test(){
  92. BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group
  93. Session session = null;
  94. Transaction tran = null;
  95. try{
  96. session = this.getSession();
  97. tran = session.beginTransaction();
  98. BlogMessage blogMessage = new BlogMessage();
  99. blogMessage.setMsgContent("css 学习笔记");
  100. blogGroup.getMessage().add(blogMessage);
  101. session.merge(blogGroup);
  102. tran.commit();
  103. } catch(Exception e){
  104. System.out.println(e.toString());
  105. tran.rollback();
  106. }
  107. }
  108. //删除某一个博客-组(BlogGroup),因为不能删除我们写的博客消息,所以不能有删除的级联操作
      //注意:我们有三个表,分别是“博客-组”, “博客-消息”,“组-消息”,当从“博客-组”中删除一条记录X时,表“博客-消息”中和X相关的数据不会删除,
      //因为我们没有设置级联关系,但是表“组-消息”中和X相关的数据会删除干净,表“组-消息”是中间关联表,一方被移除之后,该表相关数据自然被移除。
  109. public void delete_test(){
  110. BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group
  111. Session session = null;
  112. Transaction tran = null;
  113. try{
  114. session = this.getSession();
  115. tran = session.beginTransaction();
  116. session.delete(blogGroup);
  117. tran.commit();
  118. } catch(Exception e){
  119. System.out.println(e.toString());
  120. tran.rollback();
  121. }
  122. }
  123. }

罗列所有持久化类的类名:

  hibernate.cfg.xml中配置:

  1. <hibernate-configuration>
  2. <session-factory>
  3.    ...  

      <mapping class="com.blog.entriy.BlogGroup"/>
      <mapping class="com.blog.entriy.BlogMessage"/>

  1.      ...
  2. </session-factory>
  3. </hibernate-configuration>

  如果整合了Spring:application.cfg.xml中的配置<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

  1.     <!--Spring中: 包扫描的方式加载注解类 -->
  2. <property name="annotatedClasses">
  3. <list>
  4. <value>com.blog.entriy.BlogGroup</value>
  5. <value>com.blog.entriy.BlogMessage</value>
  6. </list>
  7. </property>
  8. <!-- 通过配置文件的方式获取数据源,只是通过XML管理映射方式的。
  9. <property name="mappingResources">
  10. <list>
  11. 以下用来列出所有的PO映射文件
  12. <value>publishparty.cfg.xml</value>
  13. </list>
  14. </property> -->
         .....
  15. </bean>

Hibernate注解的更多相关文章

  1. Hibernate注解----关联映射注解以及课程总结详解----图片版本

    上一篇,记录了Hibernate注解----类级别注解以及属性注解详解 ,我们这一节主要讲解的是Hibernate注解----关联映射注解以及课程总结详解. 本节的主要内容: 第3章 关联映射注解 3 ...

  2. Hibernate注解----类级别注解以及属性注解详解----图片版本

    这篇文章是我在慕课网上学习Hibernate注解的时候进行手机以及整理的笔记. 今天把它分享给大家,希望对大家有用.可以进行收藏,然后需要的时候进行对照一下即可.这样能起到一个查阅的作用. 本文主要讲 ...

  3. hibernate注解随笔—10月8日

    hibernate注解(herbinate4 jar包注解可用,使用hibernate3.3注解失败) 如果javabean与数据库中表名一致(不区分大小写),则注解不用写@Table(name=&q ...

  4. Hibernate注解使用以及Spring整合

    Hibernate注解使用以及Spring整合 原文转自:http://wanqiufeng.blog.51cto.com/409430/484739 (1) 简介: 在过去几年里,Hibernate ...

  5. Hibernate注解映射联合主键的三种主要方式

    今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...

  6. 【maven + hibernate(注解) +spring +springMVC】 使用maven搭建项目

    研究,百度,查资料+好友帮助,使用MyEcplise2015工具,通过maven搭建hibernate+springMVC+spring的项目,数据库采用MySql5.5 不过使用的版本会在项目搭建过 ...

  7. Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:

    Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长: 通过Hibernate注解的方式映射oracel数据库的sequence主键生成器 ...

  8. 。。。Hibernate注解配置的注意事项。。。

    今天本来打算录视频的,突然遇到一个拦路虎,Hibernate注解配置,有一个注意点:要么都在属性上面注解配置,要么都在getXX()方法上面用注解配置,要不然就会报错: Caused by: org. ...

  9. Hibernate注解错误之- org.hibernate.MappingException: Could not determine type for:

    Hibernate 注解 @OneToOne 时候,出现以下错误,经调试,发现 注解要么全部放在字段上,要么全部放在get方法上,不能混合使用! org.hibernate.MappingExcept ...

  10. Hibernate 注解 没有加@Column一样会在数据库创建这些字段

    Hibernate 注解 没有加@Column一样会在数据库创建这些字段 如下一个注解类: package com.hyy.hibernate.one_to_many.domain; import j ...

随机推荐

  1. C到C++的升级

    const 在C中只是个“只读变量”,并不是真正意义上的常量,通过指针能改变它,如下 #include<stdio.h> int main() { ;//声明只读变量a为0 int* p= ...

  2. winform控件在Enable=false的情况下改变它的字体颜色

    [System.Runtime.InteropServices.DllImport("user32.dll ")]         public static extern int ...

  3. maven整理——初步

    最近用到了maven,查找了很多资料,写这篇博文是为了记录maven的使用学习,也方便自己日后好查找. 在这里引用http://www.cnblogs.com/dcba1112/archive/201 ...

  4. 初识Scala反射

    我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...

  5. errno

    关于errno有以下需要注意: 1  A common mistake is to do if (somecall() == -1) {                printf("som ...

  6. DSY3163*Eden的新背包问题

    Description "寄没有地址的信,这样的情绪有种距离,你放着谁的歌曲,是怎样的心心静,能不能说给我听."失忆的Eden总想努力地回忆起过去,然而总是只能清晰地记得那种思念的 ...

  7. C#中分割字符串输出字符数组

    来自博客园 http://www.cnblogs.com/yugen/archive/2010/08/18/1802781.html   1.用字符串分隔: using System.Text.Reg ...

  8. Handlebars.js的学习

    写在开头的话: 在使用Ghost搭建自己的博客的时候,发现不会Handlebars.js寸步难行,所以本人决定学习下Handlebars.js,因此在此做个记录 为什么选择Handlebars.js ...

  9. JSP :运行最简单的 JSP 程序

    160916 1. 代码和显示效果 <%@ page contentType="text/html; charset=GB2312" %> <%@ page im ...

  10. Hbuilder开发HTML5 APP之创建子页面

    折腾了好久,终于看明白怎么创建了: 1.创建个html5的mui页面,在其初始化方法中: mui.init({   subpages:[{    id:"list",   url: ...