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的多对多双向关联的两种方案已经完成,如果觉得对你们有用的话,记得点个关注啊!!!