java中Hibernate多对多双向关联的配置

 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任

 Hibernate的双向多对多关联有两种配置方法:那我们就来看看两种方案是如何配置的。

         一、创建以各自类为类型的集合来关联

      1.首先我们要在两个实体类(雇员<Emploee>、工程<Project>)中各自给对方添加一个对方的集合

       1.1 雇员实体类

package cn.manytomany.one;

import java.util.HashSet;
import java.util.Set;

public class Emploee {
    //雇员id
    private Integer empId;
    //工程
    private String empName;
     //工程的集合
    private Set<Project> projects=new HashSet<Project>();
   
    public Set<Project> getProjects() {
        return projects;
    }
    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }
    public Integer getEmpId() {
        return empId;
    }
    public void setEmpId(Integer empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
}

 

       1.2 工程实体类

package cn.manytomany.one;

import java.util.HashSet;
import java.util.Set;

public class Project {
    private Integer proId;
    private String proName;
    private Set<Emploee> emploees=new HashSet<Emploee>();
   
    public Set<Emploee> getEmploees() {
        return emploees;
    }
    public void setEmploees(Set<Emploee> emploees) {
        this.emploees = emploees;
    }
    public Integer getProId() {
        return proId;
    }
    public void setProId(Integer proId) {
        this.proId = proId;
    }
    public String getProName() {
        return proName;
    }
    public void setProName(String proName) {
        this.proName = proName;
    }
   
}

 

 

      2.有了实体类之后呢,我们就能通过实体的属性和数据库的表字段配置映射关系。

      2.1 emploees.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.manytomany.one">
    <class name="Emploee" table="Emploee">
        <id name="empId">
        <generator class="sequence">
        <param name="sequence">SQU_NUM</param>
        </generator>
        </id>
        <property name="empName"></property>
        <set name="projects" table="PROEMP">
         <key column="RPROID"></key>
         <many-to-many class="Project" column="REMPID">
         </many-to-many>
        </set>
    </class>
</hibernate-mapping>

 

 

      2.2   projects.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.manytomany.one">
    <class name="Project" table="PROJECT">
        <id name="proId">
        <generator class="sequence">
        <param name="sequence">SQU_NUM</param>
        </generator>
        </id>
        <property name="proName"></property>
       
        <set name="emploees" table="PROEMP" cascade="save-update">
         <key column="REMPID"></key>
         <many-to-many class="Emploee" column="RPROID">
         </many-to-many>
        </set>
    </class>
</hibernate-mapping>

 

  

     2.3 另外还有一个最重要的大配置来引用两个小配置

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">
            oracle.jdbc.OracleDriver
        </property>
        <property name="connection.url">
            jdbc:oracle:thin:@localhost:1521:orcl
        </property>
        <property name="connection.username">happy</property>
        <property name="connection.password">1</property>

        <!-- SQL dialect 方言-->
        <property name="dialect">
            org.hibernate.dialect.Oracle10gDialect
        </property>

        <!-- Disable the second-level cache 二级缓存-->
        <!--<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->

        <!-- Echo all executed SQL to stdout 是否在控制台显示sql语句-->
        <property name="show_sql">true</property>

        <!-- 格式化显示SQL -->
        <property name="format_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>

        <!-- 关联小配置 -->
        <mapping resource="cn/manytomany/doubleanother/emploees.hbm.xml" />
        <mapping resource="cn/manytomany/doubleanother/projects.hbm.xml" />

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

 

 

 

    3.最后就是测试类了

package cn.manytomany.one;

import org.hibernate.Session;
import org.hibernate.Transaction;

public class ManyToManyDoubleTest {

    /**
     * 多对多的双向关联测试
     */
    public static void main(String[] args) {
        Session session = HibernateUtil.currentSession();
        Transaction tsc = session.beginTransaction();
        //创建雇员
        Emploee emp=new Emploee();
        emp.setEmpName("田超");
        Emploee emp1=new Emploee();
        emp1.setEmpName("施强");
       
        //创建工程
        Project pro=new Project();
        pro.setProName("开发工程");
        pro.getEmploees().add(emp);
        pro.getEmploees().add(emp1);
         try {
            session.save(pro);
            tsc.commit();
        } catch (Exception e) {
            // 回滚
            tsc.rollback();
        }
        HibernateUtil.closeSession();
    }

}

 

 

     3.1 最后补充一下工具类,看看就行

package cn.manytomany.one;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
/*
 * session工具类
 */
public class HibernateUtil {

    private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();
    private static Configuration cfg;
    private static final SessionFactory sf;
    static{
        try {
            cfg=new Configuration().configure();
            sf = cfg.buildSessionFactory();
        } catch (Exception e) {
            //异常
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);
        }
    }
    public static Session currentSession(){
        Session session=sessionTL.get();
        //如果session为null,则打开一个新的session
        if (session==null) {
            session=sf.openSession();
            sessionTL.set(session);
        }
        return session;
    }
    public static void closeSession(){
        Session session=sessionTL.get();
        sessionTL.set(null);
        session.close();
       
    }

}

 

 

    

     二、创建一个中间的实体类来关联

       1.跟第一个方案差不多,先实现三个实体类,代码如下:

package cn.manytomany.doubleanother;

import java.util.HashSet;
import java.util.Set;

public class Emploee {
   
    private Integer empId;
    private String empName;
    private Set<ProEmp> proemp=new HashSet<ProEmp>(); //集合的类型为中间的实体类类型
    public Set<ProEmp> getProemp() {
        return proemp;
    }
    public void setProemp(Set<ProEmp> proemp) {
        this.proemp = proemp;
    }
    public Integer getEmpId() {
        return empId;
    }
    public void setEmpId(Integer empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
   

}

 

 

package cn.manytomany.doubleanother;

import java.util.HashSet;
import java.util.Set;

public class Project {
    private Integer proId;
    private String proName;
   //集合的类型依然为中间的实体类类型
    private Set<ProEmp> proemp=new HashSet<ProEmp>();
    public Set<ProEmp> getProemp() {
     return proemp;
   }
    public void setProemp(Set<ProEmp> proemp) {
     this.proemp = proemp;
   }
   public Integer getProId() {
    return proId;
  }
   public void setProId(Integer proId) {
    this.proId = proId;
  }
   public String getProName() {
    return proName;
  }
   public void setProName(String proName) {
     this.proName = proName;
   }

}

 

 

     1.1  补充的中间实体类

   

package cn.manytomany.doubleanother;

public class ProEmp {
   
    private Integer id;
    private Emploee emp;
    private Project pro;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Emploee getEmp() {
        return emp;
    }
    public void setEmp(Emploee emp) {
        this.emp = emp;
    }
    public Project getPro() {
        return pro;
    }
    public void setPro(Project pro) {
        this.pro = pro;
    }
   
}

 

 

     2. 接下来就是小配置了,跟第一个方案格式几乎是一样的,就不过多解释了,直接来看小配置就行了。

    因为我们要用中间实体类来关联,所以雇员类(Emploee)和工程类(Project)没有什么眼添加的,只需按照正常的配置即可。

    2.1 emploees.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.manytomany.doubleanother">
    <class name="Emploee" table="Emploee">
        <id name="empId">
        <generator class="sequence">
        <param name="sequence">SQU_NUM</param>
        </generator>
        </id>
        <property name="empName"></property>
    </class>
</hibernate-mapping>

 

 

    2.2  emploees.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.manytomany.doubleanother">
    <class name="Project" table="PROJECT">
        <id name="proId">
        <generator class="sequence">
        <param name="sequence">SQU_NUM</param>
        </generator>
        </id>
        <property name="proName"></property>
    </class>
</hibernate-mapping>

 

  

     2.3 关键就在于 proemp.hbm.xml   (把多对多关联转化成两个多对一来关联)

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="cn.manytomany.doubleanother">
    <class name="ProEmp" table="PROEMPNEW">
        <id name="id">
        <generator class="sequence">
        <param name="sequence">SQU_NUM</param>
        </generator>
        </id>
        <many-to-one name="emp" class="Emploee" column="EMPID">
        </many-to-one>
        <many-to-one name="pro" class="Project" column="PROID">
        </many-to-one>
    </class>
</hibernate-mapping>

 

 

    3. 现在就可以进行测试类测试数据了

package cn.manytomany.doubleanother;

import org.hibernate.Session;
import org.hibernate.Transaction;

import cn.manytomany.one.HibernateUtil;

public class ManyToManyDoubleOnlyAnother {

    /**
     * 多对多双向关联---两个多对一关联
     */
    public static void main(String[] args) {
        Session session = HibernateUtil.currentSession();
        Transaction tsc = session.beginTransaction();
        //创建雇员
        Emploee emp=new Emploee();
        emp.setEmpName("田超");
       
        //创建工程
        Project pro=new Project();
        pro.setProName("开发工程");
       
        //中间类
        ProEmp proemp=new ProEmp();
        proemp.setEmp(emp);
        proemp.setPro(pro);
         try {
            //保存
            session.save(emp);
            session.save(pro);
            session.save(proemp);
            tsc.commit();
        } catch (Exception e) {
            // 回滚
            tsc.rollback();
        }
        HibernateUtil.closeSession();

    }

}

 

     好了, Hibernate的多对多双向关联的两种方案已经完成,如果觉得对你们有用的话,记得点个关注啊!!!

时间: 2024-09-30 17:44:37

java中Hibernate多对多双向关联的配置的相关文章

Hibernate从入门到精通(十一)多对多双向关联映射

上次我们在中Hibernate从入门到精通(十)多对多单向关联映射讲解了一下多对多单向关联映射,这次我 们讲解一下七种映射中的最后一种多对多双向关联映射. 多对多双向关联映射 按照我们之前的惯例,先看一下相关类图和代码,具体如下: public class Role { private int id; private String name; private Set users; public int getId() { return id; } public void setId(int id

java中Hibernate自动生成的问题 ?

问题描述 java中Hibernate自动生成的问题 ? 我是刚毕业不久的菜鸟,在公司做项目, 用hibernate 自动生成了与表对应的实体类和 增删改查,都是自动生成的 用的时候只需在业务层调用就行, 然后公司来了个两年经验的同事,说: " 现在都没人用Hibernate自动生成了 ,都是用jdbc 做呢, 还有java的注解", 我现在好困惑啊, Hibernate不是封装了jdbc吗? 怎么现在没人用hibernate了反而用jdbc呢? 还有自动生成不是会提高开发效率吗 ?

【hibernate框架】多对多双向关联(XML实现)

多对多的双向关联:(非常少用) 通过老师可以知道他教了多少学生,这是单项多对多.而如果同时通过学生知道有多少个老师教他,那么就是多对多双向的关联. XML实现: Student.java: package cn.edu.hpu.many2many; import java.util.HashSet; import java.util.Set; public class Student { private int id; private String name; private Set<Teach

hibernate5(11)注解映射[3]一对多多对一双向关联

在上两篇文章里,我们详细地分别讲解了一对多和多对一的单向关联配置的具体属性含义,在这一篇文章里,我们完成两者的的整合建立双向关联. 在实际的博客网站中,我们可能需要根据文章读取作者(用户)信息,但肯定也要让用户能获取自己的文章信息,针对这种需求,我们可以建立文章(多)对用户(一)的双向关联映射. 下面先看实例映射配置文件: /********************一方配置User********************/ @Entity//声明当前类为hibernate映射到数据库中的实体类

hibernate单向和双向关联问题

问题描述 hibernate的<one-to-many>和<many-to-one>有什么居别,两者要是反过来不都一样了吗还有一个问题在这一对多或者多对一得关联映射下,我们如何通过选择来维护她是单向映射还是双向映射呢我们该怎么选择是单向还是双向谢谢 解决方案 解决方案二:恩没什么区别要看站在那个立场站的立场不同映射的关系就不同你要进行维护用控制反转inverse可以指定关联关系的控制方向解决方案三:<one-to-many>和<many-to-one>这个只

【SSH系列】hibernate映射 -- 一对一双向关联映射

       开篇前言       上篇博文[SSH进阶之路]hibernate映射--一对一单向关联映射,小编介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.为什么呢,因为对象模型具有方向性,在前面的博文Hibernate基本映射中,小编介绍了单向和双向,所谓的单向就是一段只能加载另一个端,不能反过来:双向就是两端都可以加载另一端,可以这样来理解,单向就是一厢情愿,双向就是两情相悦.ok,那么问题来了,如果我

【hibernate框架】一对多(多对一)双向关联(Annotation实现)

用户和组的关联,一个用户只能属于一个组,一个组可以拥有多个用户 User.java: package cn.edu.hpu.one2many; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity

java中Hibernate session在service实现事务getCurrentSession()和openSession()区别

当我们在使用Hibernate作为数据库操作的类库时,我们一般在DAO层里与数据库相关的操作,把业务逻辑写在service层里.但是如果我们的项目比较小,那么直接在dao层里写事务也是可以的,这个就是看个人了,没有什么特别的规定.但是如果项目比较大,那么DAO应该只做单纯的数据库的操作,service写事务的操作,即整个业务逻辑. 例如:业务逻辑要求向数据库中的用户表增加一个用户,同时向日志表中加入一条日志,而这需要调用DAO的两个方法(UserDao的saveUser和LogDao的saveL

java中Hibernate中的数据库对象详解

1.hibernate.cfg.xml  代码如下 复制代码 <!DOCTYPE hibernate-configuration PUBLIC         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuratio