博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate注解
阅读量:7197 次
发布时间:2019-06-29

本文共 8850 字,大约阅读时间需要 29 分钟。

前言:

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

数据库物理模型:

数据库的描述:

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

Hibernate关联映射方式:

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

生成sql语句:

drop table if exists blogGroup;drop table if exists blogMessage;drop table if exists groupMessage;create table blogGroup(   groupId              int not null auto_increment,   groupName            varchar(50),   primary key (groupId));create table blogMessage(   msgId                int not null auto_increment,   msgContent           varchar(1000),   primary key (msgId));create table groupMessage(   groupId              int not null,   msgId                int not null,   primary key (groupId, msgId));alter table groupMessage add constraint FK_Relationship_1 foreign key (groupId)      references blogGroup (groupId) on delete restrict on update restrict;alter table groupMessage add constraint FK_Relationship_2 foreign key (msgId)      references blogMessage (msgId) on delete restrict on update restrict;

PO(persisent object)类:

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

PO : BlogGroup 

package com.blog.entriy;@Entity@Table(name="blogGroup")public class BlogGroup implements Serializable{    @Id    @Column(name="groupId")    @GeneratedValue(strategy=GenerationType.IDENTITY)    private int groupId;    @Column(name="groupName")    private String groupName;        //fetch=FetchType.EAGER 抓取实体时,立即抓取关联实体,我用的get()方式加载一个对象    //ascadeType.PERSIST, CascadeType.MERGE, 分别是更新和保存时级联    @ManyToMany(targetEntity=BlogMessage.class, cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)    @JoinTable(name="groupMessage",        joinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId"),        inverseJoinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId")    )    private Set
message = new HashSet
(); public int getGroupId() { return groupId; } public void setGroupId(int groupId) { this.groupId = groupId; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public Set
getMessage() { return message; } public void setMessage(Set
message) { this.message = message; }}

PO : BlogMessage 

package com.blog.entriy;@Entity@Table(name="blogMessage")public class BlogMessage implements Serializable{    @Id    @Column(name="msgId")    @GeneratedValue(strategy=GenerationType.IDENTITY)    private int msgId;    @Column(name="msgContent")    private String msgContent;        @ManyToMany(targetEntity=BlogGroup.class)    @JoinTable(name="groupMessage",        joinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId"),        inverseJoinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId")    )    private Set
group = new HashSet
(); public int getMsgId() { return msgId; } public void setMsgId(int msgId) { this.msgId = msgId; } public String getMsgContent() { return msgContent; } public void setMsgContent(String msgContent) { this.msgContent = msgContent; } public Set
getGroup() { return group; } public void setGroup(Set
group) { this.group = group; }}

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层:

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

package com.blog.dao;public class BlogDao {   private SessionFactory sessionFactory;          public Session getSession() {          return sessionFactory.getCurrentSession();      }        public SessionFactory getSessionFactory() {          return sessionFactory;      }        public void setSessionFactory(SessionFactory sessionFactory) {          this.sessionFactory = sessionFactory;      }          public BlogGroup get_test(int id){        BlogGroup blogGroup = null;        Session session = null;        Transaction tran = null;        try{            session = this.getSession();            tran = session.beginTransaction();            blogGroup = (BlogGroup)session.get(BlogGroup.class, id);            tran.commit();        } catch(Exception e){            System.out.println(e.toString());            tran.rollback();        }        return blogGroup;    }      //只插入一端博客-组(BlogGroup)    public void insert_test1(){        Session session = null;        Transaction tran = null;        try{            session = this.getSession();            tran = session.beginTransaction();            BlogGroup blogGroup = new BlogGroup();            blogGroup.setGroupName("html");            session.save(blogGroup);            tran.commit();        } catch(Exception e){            System.out.println(e.toString());            tran.rollback();        }    }    //同时插入两端(博客-组 和 博客-消息),没有用cascade级联操作,所以BlogGroup和BlogMessage两端都要先持久化    public void insert_test2(){        Session session = null;        Transaction tran = null;        try{            session = this.getSession();            tran = session.beginTransaction();            BlogGroup blogGroup = new BlogGroup();            blogGroup.setGroupName("c++");            BlogMessage blogMessage = new BlogMessage();            blogMessage.setMsgContent("c++ primer");            session.save(blogMessage);            Set
message = new HashSet
(); message.add(blogMessage); blogGroup.setMessage(message); session.save(blogGroup); tran.commit(); } catch(Exception e){ System.out.println(e.toString()); tran.rollback(); } } //同时插入两端,对BlogGroup设置persist级联操作 @ManyToMany(cascade={CascadeType.PERSIST}) public void insert_test3(){ Session session = null; Transaction tran = null; try{ session = this.getSession(); tran = session.beginTransaction(); BlogGroup blogGroup = new BlogGroup(); blogGroup.setGroupName("javaee"); BlogMessage blogMessage = new BlogMessage(); blogMessage.setMsgContent("Spring+hibernate+struct"); blogGroup.getMessage().add(blogMessage); session.persist(blogGroup); tran.commit(); } catch(Exception e){ System.out.println(e.toString()); tran.rollback(); } } //向博客-组(BlogGroup)添加新的 博客-消息(BlogMessage),对BlogGroup再添加一个更新的级联操作,CascadeType.MERGE public void update_test(){ BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group Session session = null; Transaction tran = null; try{ session = this.getSession(); tran = session.beginTransaction(); BlogMessage blogMessage = new BlogMessage(); blogMessage.setMsgContent("css 学习笔记"); blogGroup.getMessage().add(blogMessage); session.merge(blogGroup); tran.commit(); } catch(Exception e){ System.out.println(e.toString()); tran.rollback(); } } //删除某一个博客-组(BlogGroup),因为不能删除我们写的博客消息,所以不能有删除的级联操作   //注意:我们有三个表,分别是“博客-组”, “博客-消息”,“组-消息”,当从“博客-组”中删除一条记录X时,表“博客-消息”中和X相关的数据不会删除,   //因为我们没有设置级联关系,但是表“组-消息”中和X相关的数据会删除干净,表“组-消息”是中间关联表,一方被移除之后,该表相关数据自然被移除。 public void delete_test(){ BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group Session session = null; Transaction tran = null; try{ session = this.getSession(); tran = session.beginTransaction(); session.delete(blogGroup); tran.commit(); } catch(Exception e){ System.out.println(e.toString()); tran.rollback(); } }}

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

  hibernate.cfg.xml中配置:

   ...  

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

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

     ...       

 

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

    
com.blog.entriy.BlogGroup
com.blog.entriy.BlogMessage
     .....

 

转载地址:http://fxtkm.baihongyu.com/

你可能感兴趣的文章
Scrapy框架基础使用
查看>>
python学习笔记-(一)初识python
查看>>
前端的事件流以及事件处理程序
查看>>
react中create-react-app详情配置文档
查看>>
TLD单目标跟踪算法程序详解--OpenTLD Code 详解
查看>>
PDO基础知识
查看>>
汉诺塔问题(C++版)
查看>>
Basler和Matrox的配置及调试
查看>>
VirtualBOX 不能mount优盘,移动硬盘解决方案
查看>>
漫画:全面理解java.lang.IllegalArgumentException及其可用性设计
查看>>
[解题报告] 100 - The 3n + 1 problem
查看>>
SpringMVC HelloWorld实例开发及部署
查看>>
从最小割角度解决最大权闭合图问题及其在二分图形式下的优化
查看>>
sencha-touch2.0控件nestlist的简单用法
查看>>
python学习之控制语句
查看>>
Android Activity和Intent机制学习笔记
查看>>
装饰器复习
查看>>
pymysql数据库操作
查看>>
elasticsearch问题解决之分片副本UNASSIGNED
查看>>
|"|&|<|>等html字符转义
查看>>