一、一对多关联关系映射(双向关联)
一对多关联关系站在一方角度考虑是一对多、站在多方角度考虑是多对一
一个国家(Country)有多个部长(Minister)、一个部长只属于一个国家
1.1Country类、及其映射文件Country.hbm.xml
package edu.aeon.beans; import java.util.HashSet; import java.util.Set; /** * [说明]:Country(国家)实体类 * @author aeon * */ public class Country { /**国家id*/ private Integer cid; /**国家名*/ private String cname; /**一个国家里部长集合*/ private Set<Minister> ministers; public Country() { super(); //初始化 ministers=new HashSet<Minister>(); } public Country(String cname) { this(); this.cname = cname; } public Integer getCid() { return cid; } public void setCid(Integer cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } public Set<Minister> getMinisters() { return ministers; } public void setMinisters(Set<Minister> ministers) { this.ministers = ministers; } @Override public String toString() { return "Country [cid=" + cid + ", cname=" + cname + ", minister=" + ministers + "]"; } }
Country.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="edu.aeon.beans"> <class name="Country"> <id name="cid"> <column name="cid" sql-type="int(3)"/> <generator class="native"/> </id> <property name="cname"> <column name="cname" sql-type="varchar(16)"/> </property> <!-- 关联属性的映射配置 --> <!-- name:关联属性的属性名 --> <set name="ministers" cascade="save-update"> <!-- 关联的外键 --> <key column="countryid" /> <!-- 关联到那个类 --> <one-to-many class="Minister"/> </set> </class> </hibernate-mapping>
1.2Minister及其映射文件Minister.hbm.xml
package edu.aeon.beans; /** * [说明]:minister(部长)实体类 * @author aeon * */ public class Minister { /**部长id*/ private Integer mid; /**部长名*/ private String mname; /**属于的国家*/ private Country country; public Minister() { } public Minister(String mname) { super(); this.mname = mname; } public Integer getMid() { return mid; } public void setMid(Integer mid) { this.mid = mid; } public String getMname() { return mname; } public void setMname(String mname) { this.mname = mname; } public Country getCountry() { return country; } public void setCountry(Country country) { this.country = country; } @Override public String toString() { return "Minister [mid=" + mid + ", mname=" + mname + "]"; } }
Minister.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="edu.aeon.beans"> <class name="Minister"> <id name="mid"> <column name="mid" sql-type="int(3)"/> <generator class="native"/> </id> <property name="mname"> <column name="mname" sql-type="varchar(16)"/> </property> <!-- 站在自己(minister)的角度属于多对一 name="country":关联的属性名 class="Country":关联的属性类型 cascade="save-update":设置级联保存方式保存己方的同时更新对方表 column name="countryid":代表关联的主键 --> <many-to-one name="country" class="Country" cascade="save-update"> <column name="countryid"/> </many-to-one> </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> <!-- 配置数据库的四要素 --> <property name="hibernate.connection.driver">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/db_test</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 配置数据库方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 配置数据库连接池 --> <!-- <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property> --> <!-- 注册当前session上下文 --> <property name="hibernate.current_session_context_class">thread</property> <!-- 自动建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 显示sql --> <property name="hibernate.show_sql">true</property> <!-- 格式化sql --> <property name="hibernate.format_sql">true</property> <mapping resource="edu/aeon/beans/Country.hbm.xml"/> <mapping resource="edu/aeon/beans/Minister.hbm.xml"/> <!-- <mapping resource="sqlMapping.xml"/> --> </session-factory> </hibernate-configuration>
1.3测试类
package edu.aeon.hibernate.test; import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test; import edu.aeon.aeonutils.hibernate.getsessionutil.GetSessionUtil; import edu.aeon.beans.Country; import edu.aeon.beans.Minister; /** * [说明]:测试类 * @author aeon * */ public class HibernateTest { /** * 测试1对多关联关系 */ @Test public void testOne2Many(){ Session session=null; Transaction transaction=null; try { session = GetSessionUtil.getSession(); System.out.println(session); transaction = session.getTransaction(); System.out.println(transaction); transaction.begin(); //Country维护关联关系 /*Minister minister1=new Minister("部长甲"); Minister minister2=new Minister("部长乙"); Country country=new Country("china"); country.getMinisters().add(minister1); country.getMinisters().add(minister2); session.save(country);*/ //Minister维护关联关系、谁维护保存谁 Minister minister1=new Minister("张部长"); Country country=new Country("中国"); minister1.setCountry(country); session.save(minister1); transaction.commit(); } catch (Exception e) { transaction.rollback(); e.printStackTrace(); } } }
测试结果控制台输出:
Hibernate: create table Country ( cid int(3) not null auto_increment, cname varchar(16), primary key (cid) ) Hibernate: create table Minister ( mid int(3) not null auto_increment, mname varchar(16), countryid integer, primary key (mid) ) Hibernate: alter table Minister add constraint FKc9dntt9ob26y2m3b5ydae4dva foreign key (countryid) references Country (cid) ThreadLocalSessionContext.TransactionProtectionWrapper[SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] org.hibernate.engine.transaction.internal.TransactionImpl@508c825 Hibernate: insert into Country (cname) values (?) Hibernate: insert into Minister (mname, countryid) values (?, ?)
本次用到的工具类GetSessionUtil.java前面已经附上了。