dljd_(062-065)_hibernate关联关系映射_单向关联
一、一对多关联关系映射(单向关联)
一个国家(Contry)有多个部长(Minister)
1.1定义Country实体类及其到数据库之间的映射(Country.hbm.xml)
package edu.aeon.beans; import java.util.Set; /** * [说明]:Country(国家)实体类 * @author aeon * */ public class Country { /**国家id*/ private Integer cid; /**国家名*/ private String cname; /**一个国家里部长集合*/ private Set<Minister> ministers; public Country() { super(); } public Country(String cname) { super(); 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"> <!-- 关联的外键 --> <key column="countryid" /> <!-- 关联到那个类 --> <one-to-many class="Minister"/> </set> </class> </hibernate-mapping>
1.2定义Minister实体类及其到数据库之间的映射(Minister.hbm.xml)
package edu.aeon.beans; /** * [说明]:minister(部长)实体类 * @author aeon * */ public class Minister { /**部长id*/ private Integer mid; /**部长名*/ private String mname; 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; } @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> </class> </hibernate-mapping>
1.3然后将Country.hbm.xml和Minister.hbm.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.4测试类
package edu.aeon.hibernate.test; import java.util.HashSet; import java.util.Set; 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(); //操作 Minister minister1=new Minister("部长甲"); Minister minister2=new Minister("部长乙"); Set<Minister> ministers=new HashSet<Minister>(); ministers.add(minister1); ministers.add(minister2); Country country=new Country("china"); country.setMinisters(ministers); session.save(minister1); session.save(minister2); session.save(country); 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@714c7f58 Hibernate: insert into Minister (mname) values (?) Hibernate: insert into Minister (mname) values (?) Hibernate: insert into Country (cname) values (?) Hibernate: update Minister set countryid=? where mid=? Hibernate: update Minister set countryid=? where mid=?
执行结果截图:
此时数据库信息截图如下:
______________________________________________one2many最终版整理如下__________________________________________________________
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>
测试类:
package edu.aeon.hibernate.test; import java.util.HashSet; import java.util.Set; 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(); //操作 Minister minister1=new Minister("部长甲"); Minister minister2=new Minister("部长乙"); Country country=new Country("china"); country.getMinisters().add(minister1); country.getMinisters().add(minister2); session.save(country); transaction.commit(); } catch (Exception e) { transaction.rollback(); e.printStackTrace(); } } }
其它一律保持不变、测试结果同上。
本次程序用到了前面写的一个获取session和sessionFactory的工具类:
package edu.aeon.aeonutils.hibernate.getsessionutil; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * [说明]:获取session的工具类 * @author aeon */ public class GetSessionUtil { private static SessionFactory sessionFactory; /** * session获取的第一种写法 * 由于SessionFactory是一个重量级的对象、这样写没获取一次session都要相应的创建一次SessionFactory对象 * 创建与销毁时系统开销大、所以不建议使用 * @return public static Session getSession(){//最好别用 return new Configuration().configure().buildSessionFactory().getCurrentSession(); } */ /** * 通过session工厂获取session * @return */ public static Session getSession(){ return getSessionFactory().getCurrentSession(); } /** * 通过配置文件中的配置的session工厂项来实例化session工厂 * @return */ public static SessionFactory getSessionFactory() { if(null==sessionFactory||sessionFactory.isClosed()){ sessionFactory=new Configuration().configure().buildSessionFactory(); } return sessionFactory; } /** * 测试 * @param args */ public static void main(String[] args) { System.out.println(GetSessionUtil.getSessionFactory()==GetSessionUtil.getSessionFactory());//结果true System.out.println(GetSessionUtil.getSession()==GetSessionUtil.getSession());//结果true System.out.println(GetSessionUtil.getSessionFactory().getCurrentSession()==GetSessionUtil.getSession());//结果true } }