zoukankan      html  css  js  c++  java
  • Hibernate注解

    前言:

      最近正在学习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<BlogMessage> message = new HashSet<BlogMessage>();
        
        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<BlogMessage> getMessage() {
            return message;
        }
        public void setMessage(Set<BlogMessage> 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<BlogGroup> group = new HashSet<BlogGroup>();
        
        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<BlogGroup> getGroup() {
            return group;
        }
        public void setGroup(Set<BlogGroup> 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<BlogMessage> message = new HashSet<BlogMessage>(); 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中配置:

     <hibernate-configuration> 
         <session-factory> 
           ...  

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

         ...
         </session-factory> 
     </hibernate-configuration> 

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

        <!--Spring中: 包扫描的方式加载注解类 -->
            <property name="annotatedClasses">
                <list>
                    <value>com.blog.entriy.BlogGroup</value>
                    <value>com.blog.entriy.BlogMessage</value>
                </list>
            </property>    
           
           <!--  通过配置文件的方式获取数据源,只是通过XML管理映射方式的。
            <property name="mappingResources">
                <list>
                   以下用来列出所有的PO映射文件
                    <value>publishparty.cfg.xml</value>
                </list>
            </property>        -->
         .....
    </bean>
  • 相关阅读:
    @PathVariable("cart_id") @RequestParam("ur") @RequestBody 比较
    将字符串数组解析为数组
    org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type: class ...
    nacos+openFeign #找不到服务 feign.FeignException$NotFound: status 404 reading
    java生成一个范围的数字
    栏中栏
    百度PaddlePaddle入门-4(5步法之八股文)
    百度PaddlePaddle入门-3(框架)
    百度PaddlePaddle入门-2(使用Numpy构建神经网络)
    MachineLearning入门-3(hello word)
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/5065409.html
Copyright © 2011-2022 走看看