本文解决问题:Hibernate 中配置项目(Project) 员工(Employee) 双向多对多关联
方案一:直接配置双向多对多
方案二:配置第三个关联类(xml) 将多对多查分开来(形成两个单向多对一关联 完成双向多对多关系)
方案一:直接配置双向多对多
创建Employee持久化类
1 public class Employee implements java.io.Serializable { 2 3 // Fields 4 5 private Integer empid; 6 7 private String empname; 8 9 private Set<Project> projects = new HashSet<Project>(); 10 11 ...其他内容省略 12 13 }
创建Project持久化类
public class Project implements java.io.Serializable { private Integer proid; private String proname; private Set<Employee> employees = new HashSet<Employee>(); ...其他内容省略 }
分别创建两个小配置文件(hbm.xml文件)
创建Employee.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> <class name="cn.happy.daymanymany.Employee" table="EMPLOYEE"> <id name="empid" type="java.lang.Integer"> <column name="EMPID"/> <generator class="sequence"> <param name="sequence">SEQ_ID</param> </generator> </id> <property name="empname" type="java.lang.String"> <column name="EMPNAME" length="32" not-null="true" /> </property> <set name="projects" inverse="true" table="PROEMP"> <key column="REMPID"/><!-- 表PROEMP的外键REMPID --> <many-to-many class="cn.happy.daymanymany.Project" column="RPROID" /> </set> </class> </hibernate-mapping>
创建Project.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> <class name="cn.happy.daymanymany.Project" table="PROJECT"> <id name="proid" type="java.lang.Integer"> <column name="PROID"/> <generator class="sequence"> <param name="sequence">SEQ_ID</param> </generator> </id> <property name="proname" type="java.lang.String"> <column name="PRONAME" length="32" not-null="true" /> </property> <set name="employees" table="PROEMP" cascade="save-update"> <key column="RPROID" /> <many-to-many class="cn.happy.daymanymany.Employee" column="REMPID" /> </set> </class> </hibernate-mapping>
hibernate.cfg.xml主配置文件 (创建大配置文件)
<?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 name="foo"> <property name="connection.driver_class">oracle.jdbc.OracleDriver</property> <property name="connection.url">jdbc:oracle:thin:@localhost:1521:HR</property> <property name="connection.username">happy</property> <property name="connection.password">happy</property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping resource="cn/happy/daymanymany/Project.hbm.xml"/> <mapping resource="cn/happy/daymanymany/Employee.hbm.xml"/> </session-factory> </hibernate-configuration>
书写测试类
public static SessionFactory factory; // 创建Session对象 public static Session session; // 通过代码块赋值 static { factory = new Configuration().configure().buildSessionFactory(); session = factory.openSession(); } @Test public void addTest(){ Transaction tran = null; try { tran = session.beginTransaction(); //创建EMP对象 Employee emp=new Employee(); emp.setEmpname("李小龙"); //创建Pro对象 Project pro=new Project(); pro.setProname("海淀花园"); //指定工程需要的员工 pro.getEmployees().add(emp); //指定员工所属的工程 emp.getProjects().add(pro); session.save(pro); // 事务提交 tran.commit(); System.out.println("成功"); } catch (Exception e) { e.printStackTrace(); if (tran != null) { tran.rollback(); } throw new RuntimeException("错误"); } finally { // 关闭session session.close(); } } 注意:双向多对多,还可以拆成两个多对一 <many-to-one name="emp" class="Employee">
<column name="empid"></column> </many-to-one> <many-to-one name="pro" class="Project"> <column name="proid"></column> </many-to-one>
方案二:配置第三个关联类(xml) 将多对多查分开来(形成两个单向多对一关联 完成双向多对多关系)
(完成与上方同样的功能)分别创建 Employee类、Project类、ProEmp类 ...hbm.xml
创建Employee持久化类
public class Employee implements java.io.Serializable { private Integer empid; private String empname; private Set<ProEmp> projects = new HashSet<ProEmp>(); ...其他内容省略 getter() and setter() }
创建Project持久化类
public class Project implements java.io.Serializable { private Integer proid; private String proname; private Set<ProEmp> employees = new HashSet<ProEmp>(); ...其他内容省略 }
创建ProEmp持久化类
public class ProEmp implements Serializable { private Integer id; private Project pro; private Employee emp;
现在来看 拆分后就成了 Employee和Project 分别于ProEmp一对多单向关联的关系了 所以 Employee.hbm.xml和Project.hbm.xml就不必再去关注了。
直接就是ProEmp.hbm.xml 的配置了
创建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.happy.daymanymany"> <class name="ProEmp" table="PROEMP"> <id name="id" type="java.lang.Integer"> <column name="ID"/> <!-- PROEMP表id字段 --> <generator class="sequence"> <param name="sequence">SEQ_ID</param> </generator> </id> <!-- 配置PROEMP与Employee关联
name:“emp” 指的是PROEMP 类中的相关字段
“empid”指的是Employee 类主键列
--> <many-to-one name="emp" class="Employee"> <column name="empid"></column> </many-to-one>
<!-- 配置PROEMP与Employee关联
name:“emp” 指的是PROEMP 类中的相关字段
“empid” 指的是Employee 类主键列
-->
<many-to-one name="pro" class="Project">
<column name="proid"></column>
</many-to-one> </class>
</hibernate-mapping>
测试方案二:
@Test public void many_many_test3(){ Session session = HibernateUtil.getSession(); session.beginTransaction(); Employee emp1 = new Employee(); emp1.setEname("王哲2"); //Project project1 = new Project("1号项目"); ProEmp p = (ProEmp)session.load(ProEmp.class,new Integer(3)); ProEmp proemp = new ProEmp(); proemp.setEmp(emp1); proemp.setPro(project1); session.save(emp1); session.save(project1); session.save(proemp); session.getTransaction().commit(); System.out.println("ok"); }