Hibernate多对多操作

Posted 一条路上的咸鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate多对多操作相关的知识,希望对你有一定的参考价值。

1、首先创建两个实体类(订单类和商品类)

订单类:

/**
     * 在多对多关系中,在多的那一方,必须要有一个set集合属性来保存一个那个实体
     * 并提供共有的getter和setter方法。
     */
    private Set<Good> getSet = new HashSet<Good>();
    
    /**
     * @return the getSet
     */
    public Set<Good> getGetSet() {
        return getSet;
    }
    /**
     * @param getSet the getSet to set
     */
    public void setGetSet(Set<Good> getSet) {
        this.getSet = getSet;
    }

商品类:

    /**
     * 在多对多关系中,在多的那一方,必须要有一个set集合属性来保存一个那个实体
     * 并提供共有的getter和setter方法。
     */
    private Set<Order> getOrders = new HashSet<Order>() ;
    public Set<Order> getGetOrders() {
        return getOrders;
    }
    public void setGetOrders(Set<Order> getOrders) {
        this.getOrders = getOrders;
    }

2、配置映射文件

  商品类映射文件

 <hibernate-mapping>
        <class name="com.jack.entity.Good" table="t_good">
            <id name="gid" column="gid">
                <generator class="native"></generator>
            </id>
            <property name="gname" column="gname"></property>
            <property name="gmessage" column="gmessage"></property>
            
             <!-- 
                 name属性的值:该实体中表示另一个实体的set对象名称
                 <key>中column属性的值:第三张表中外键的名称
                 class属性的值:另一个类的全路径
                 column属性的值:另一个实体类在第三张表中的外键的名称
              -->
           <set name="getOrders" table="good_order"  cascade="save-update,delete">
               <key column="goodid"></key>
               <many-to-many class="com.jack.entity.Order" column="orderid" />
           </set>
        </class>
    </hibernate-mapping>

订单类映射文件

 <hibernate-mapping>
        <class name="com.jack.entity.Order" table="t_order">
            <id name="oid" column="oid">
                <generator class="native"></generator>
            </id>
            <property name="oname" column="oname"></property>
            <property name="omessage" column="omessage"></property>
             <!-- 
             name属性的值:该实体中表示另一个实体的set对象名称
                 <key>中column属性的值:第三张表中外键的名称
                 class属性的值:另一个类的全路径
                 column属性的值:另一个实体类在第三张表中的外键的名称
              -->
           <set name="getSet" table="good_order" >
               <key column="orderid"></key>
               <many-to-many class="com.jack.entity.Good" column="goodid" />
           </set>
        </class>
    </hibernate-mapping>

3、编写核心配置文件

<hibernate-configuration>
        <session-factory>
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">root</property>
            
            <property name="hibernate.show_sql">true</property>
            <property name="hibernate.format_sql">true</property>
            <property name="hibernate.hbm2ddl.auto">update</property>
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            <property name="hibernate.current_session_context_class">thread</property>
       
            <mapping resource="com/jack/entity/Good.hbm.xml"/>
            <mapping resource="com/jack/entity/Order.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>

4、编写工具类

public class HibernateUtils {
    
    private static Configuration configuration = null;
    private static SessionFactory sessionFactory = null;
    
    
    static{
        configuration = new Configuration().configure();
        sessionFactory = configuration.buildSessionFactory();
    }

    public static Session getSeeion() {
        return sessionFactory.getCurrentSession();
    }
}

5、编写测试类

    @Test
    public void TestAdd(){
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSeeion();
            tx = session.beginTransaction();
            /**
             * 创建两个商品
             */
            Good good1 = new Good();
            good1.setGname("蛋糕");
            good1.setGmessage("奶油蛋糕");
            
            Good good2 =new Good();
            good2.setGname("牙膏");
            good2.setGmessage("冷酸灵牙膏");
            /**
             * 创建三个订单
             */
            Order order1 = new Order();
            order1.setOname("订单1");
            order1.setOmessage("001111");
            
            Order order2 = new Order();
            order2.setOname("订单2");
            order2.setOmessage("002222");
            
            Order order3 = new Order();
            order3.setOname("订单3");
            order3.setOmessage("003333");
            
            /**
             * 建立关系,把订单放到商品里
             */
            
            good1.getGetOrders().add(order1);
            good1.getGetOrders().add(order2);
            
            good2.getGetOrders().add(order2);
            good2.getGetOrders().add(order3);
            /**
             * 保存商品
             */
            session.save(good1);
            session.save(good2);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }finally{
            
        }    
    }
    

7、测试结果

8、级联删除

@Test
    public void TestDelete(){
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSeeion();
            tx = session.beginTransaction();
            /**
             * 查找蛋糕
             */
            Good good1 =session.get(Good.class, 1);
        
            /**
             * 删除蛋糕
             */
    
            session.delete(good1);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }finally{
            
        }    
    }

9、级联删除结果

有结果可见,级联删除存在一定的问题,因此在删除是不使用,而是使用维护第三张表的方式来删除。

10、维护第三张表

添加维护(将蛋糕加进第三张订单)

    @Test
    public void TestAdd(){
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSeeion();
            tx = session.beginTransaction();
            /**
             * 查找蛋糕
             */
            Good good1 =session.get(Good.class, 1);
            /**
             * 查找
             */
            Order order3 = session.get(Order.class, 3);
            /**
             * 将订单放进商品中
             */
            good1.getGetOrders().add(order3);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }finally{
            
        }    
    }

测试结果

删除维护(将蛋糕从第二张订单删除)

@Test
    public void TestDelete(){
        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSeeion();
            tx = session.beginTransaction();
            /**
             * 查找蛋糕
             */
            Good good1 =session.get(Good.class, 1);
            /**
             * 查找
             */
            Order order2 = session.get(Order.class, 2);
            /**
             * 将订单放进商品中
             */
            good1.getGetOrders().remove(order2);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
        }finally{
            
        }    
    }

测试结果:

 

以上是关于Hibernate多对多操作的主要内容,如果未能解决你的问题,请参考以下文章

2018.11.4 Hibernate中多对多的关系

Hibernate多对多操作

hibernate多对多

(十三)Hibernate中的多表操作:单向多对多

一口一口吃掉Hibernate——多对多关联映射

Hibernate-ORM:12.Hibernate中的多对多关联关系