Hibernate-多对多关系映射

多对多关系映射:

多对多和之前的一对多和多对一的区别就是需要再维护一个表,去存储两表的id,然后将两边进行关联起来

我们就以Developer和Project多对多的关系就行说明



首先建立实体类Developer.java,并建立getter和setter方法,属性如下,

private int d_id;
private String d_name;
// 开发人员,参数的多个项目
private Set<Project> projects = new HashSet<Project>();


再建立实体类Project.java,属性如下:

private int prj_id;
private String prj_name;
// 项目下的多个员工
private Set<Developer> developers = new HashSet<Developer>();

然后对应写出主配置文件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>
    	<!-- jdbc驱动类 -->
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <!-- jdbc的url -->
        <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:XE</property>
        <!-- jdbc的用户名 -->
        <property name="hibernate.connection.username">evan</property>
        <!-- jdbc的密码 -->
        <property name="hibernate.connection.password">123</property>
		<!-- 打印映射信息 -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">create</property>
        <!-- 方言 -->
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        
        <!-- 配置c3p0连接池 -->
        <!-- 最大连接数 -->
        <property name="hibernate.c3p0.max_size">20</property>
        <!-- 最小连接数 -->
        <property name="hibernate.c3p0.min_size">1</property>
        <!-- 获取连接超时时间,若超过这个时间会抛出异常,单位:毫秒 -->
        <property name="hibernate.c3p0.timeout">5000</property>
        <!-- 创建PreparedStatement对象的最大数量 -->
        <property name="hibernate.c3p0.max_statements">100</property>
        <!-- 每个指定时间检查连接池中的空闲连接,时间单位:秒 -->
        <property name="hibernate.c3p0.idle_test_period">150</property>
        <!-- 当连接池使用完毕,c3p0再和数据库建立n个连接放置到连接池中 -->
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <!-- 每次都验证连接是否可用 -->
        <property name="hibernate.c3p0.validate">true</property>
        
        <!-- 将session与当前线程绑定 -->
        <property name="current_session_context_class">thread</property>
        <!-- 映射路径 -->
        <!-- <mapping resource="cn/qblank/hibernate/entity/stu.hbm.xml"/> -->
        <!-- <mapping resource="cn/qblank/hibernate/entity/employee.hbm.xml"/>
        <mapping resource="cn/qblank/hibernate/entity/dept.hbm.xml"/> -->
   	</session-factory>
</hibernate-configuration>



然后再对应地写出实体类的映射文件

project.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
<hibernate-mapping package="cn.qblank.hibernate.entity">
	<class name="Project" table="t_project">
		<id name="prj_id" type="integer">
			<generator class="native"></generator>
		</id>
		<property name="prj_name" column="prj_name" type="string"></property>
		<!-- 
			多对多映射:
			1.  映射的集合属性: “developers”
			2.  集合属性,对应的中间表: “t_relation”
			3. 外键字段:  prjId
			4. 外键字段,对应的中间表字段:  did
			5.   集合属性元素的类型
		 -->
		<set name="developers" table="t_realation" cascade="all">
			<key column="prjId"></key>
			<many-to-many column="did" class="Developer"></many-to-many>
		</set>
	</class>	
</hibernate-mapping>

developer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
        
<hibernate-mapping package="cn.qblank.hibernate.entity">
	<class name="Developer" table="t_developer">
			<id name="d_id" type="integer">
				<generator class="native"></generator>
			</id>
			<property name="d_name" column="d_name" type="string"></property>
			<!-- 
			多对多映射配置: 员工方
				name  指定映射的集合属性
				table 集合属性对应的中间表
				key   指定中间表的外键字段(引用当前表t_developer主键的外键字段)
				many-to-many
					column 指定外键字段对应的项目字段
					class  集合元素的类型
		 	-->
			<set name="projects" table="t_realation">
				<key column="did"></key>
				<many-to-many column="prjId" class="Project"></many-to-many>
			</set>
	</class>
</hibernate-mapping>

接下来,我们就来测试一下
package cn.qblank.hibernate.test;


import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import cn.qblank.hibernate.entity.Developer;
import cn.qblank.hibernate.entity.Project;

public class ManyToMany {
	private static SessionFactory factory;
	private static Transaction trans = null;
	static {
		factory = new Configuration()
			.configure()
			.addClass(Project.class)   
			.addClass(Developer.class)   // 测试时候使用
			.buildSessionFactory();
	}
	
	public static void main(String[] args) {
		save();
	}
	// 1. 多对多,保存  【只能通过一方维护另外一方,不能重复维护!】
		public static void save() {
			Session session = factory.openSession();
			trans = session.beginTransaction();
			/*
			 * 模拟数据: 
				京东商城(老王,evan)
				租车系统(老丁,evan)
			 */
			// 创建项目对象
			Project prj_jd = new Project();
			Project prj_zc = new Project();
			prj_jd.setPrj_name("京东商城");
			prj_zc.setPrj_name("租车系统");
			// 创建员工对象
			Developer dev_evan = new Developer();
			Developer dev_wang = new Developer();
			Developer dev_ding = new Developer();
			dev_evan.setD_name("evan");
			dev_wang.setD_name("老王");
			dev_ding.setD_name("老丁");
			// 关系 【项目方】
			//京东商城
			prj_jd.getDevelopers().add(dev_evan);
			prj_jd.getDevelopers().add(dev_wang);
			//租车系统
			prj_zc.getDevelopers().add(dev_evan);
			prj_zc.getDevelopers().add(dev_ding);
			try {
				// 保存
				//插入项目
				session.save(prj_jd);
				session.save(prj_zc);   // 必须要设置级联保存 
				trans.commit();
			} catch (HibernateException e) {
				e.printStackTrace();
				trans.rollback();
			}finally{
				session.close();
			}
		}
}

运行结果如下:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into t_project (prj_name, prj_id) values (?, ?)
Hibernate: insert into t_developer (d_name, d_id) values (?, ?)
Hibernate: insert into t_developer (d_name, d_id) values (?, ?)
Hibernate: insert into t_project (prj_name, prj_id) values (?, ?)
Hibernate: insert into t_developer (d_name, d_id) values (?, ?)
Hibernate: insert into t_realation (prjId, did) values (?, ?)
Hibernate: insert into t_realation (prjId, did) values (?, ?)
Hibernate: insert into t_realation (prjId, did) values (?, ?)
Hibernate: insert into t_realation (prjId, did) values (?, ?)


数据库的表的结果如下:






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值