单向的一对多关联关系(One to Many)
对象模型关系分析:
少的一端:会通过引用一个多端的集合对象,建立对象模型关系
多的一端:没有任何变化,不知道和少的一端存在着关系。
关系模型分析:
少的一端:没有任何变化
多的一端:会和少的一端建立外键关系
使用时需要少的一端所对应的XXX.hbm.xml中进行配置
<bag name="对多的一端对象集合的属性名称">
<!-- 用key元素指定关联的外键列,会在多的一端所对应的表中产生 -->
<key column="account_id" />
<!-- 用one-to-many元素关联到多端的实体类 -->
<one-to-many class="多的一端类的全限定名称" />
</bag>
注意:
注意:
在有映射关系的实体类中,对于普通属性会进行数据的立即加载,而对于非普通属性默认采用的是延迟加载。
可以在XXX.hbm.xml关联文件中通过指定lazy="false" 采取立即加载方式。
对延迟加载的对象也可以使用Hibernate.initialize(Object proxy);方法进行强制初始化。
package model; /** * @author sally * 单向的多对一 * 少的一端 */ public class Dept { private int id; private String deptName; public Dept(){ } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
package model; import java.util.Date; /** * * @author sally * Many to One * 多的一端 */ public class Employee { private int id; private String empName; private Date hiredate; //对一端的引用 private Dept dept; public Employee(){ } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName; } public Date getHiredate() { return hiredate; } public void setHiredate(Date hiredate) { this.hiredate = hiredate; } public Dept getDept() { return dept; } public void setDept(Dept dept) { this.dept = dept; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- name属性指定类名(全限定名) table指明表名,不指明table数据默认的表名和实体名一致 --> <class name="model.Dept" table="dept_tab"> <!-- type指明当前字段的类型 name对应实体中的属性名 --> <id type="integer" name="id"> <!-- 提供ID自增的策略 native会根据数据库自行判断 --> <generator class="native"/> </id> <property name="deptName" type="string"></property> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- name属性指定类名(全限定名) table指明表名,不指明table数据默认的表名和实体名一致 --> <class name="model.Employee" table="emp_tab"> <!-- type指明当前字段的类型 name对应实体中的属性名 --> <id type="integer" name="id"> <!-- 提供ID自增的策略 native会根据数据库自行判断 --> <generator class="native"/> </id> <property name="empName" type="string"></property> <property name="hiredate" type="timestamp"></property> <!-- 用 many-to-one 元素映射多对一关联 name属性:指定关联的属性名 column属性:指定此关联属性在数据库表中的外键字段名 --> <many-to-one name="dept" column="dept_id"></many-to-one> </class> </hibernate-mapping>
<!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.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- 数据库驱动 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///m2o</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="hibernate.show_sql">true</property> <!-- 其它属性配置 --> <!-- 指明C3P0的提供者 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!-- 连接池参数的配置 --> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">30</property> <property name="hibernate.c3p0.timeout">1800</property> <property name="hibernate.c3p0.max_statements">50</property> <!-- 打印SQL语句到控制台 --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 注册实体的对象关系映射文件 --> <mapping resource="model/Dept.hbm.xml"/> <mapping resource="model/Employee.hbm.xml"/> </session-factory> </hibernate-configuration>
package test; import java.util.Date; import model.Dept; import model.Employee; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.Test; import util.HibernateUtils; public class EmployeeTest { @Test public void createTable(){ Configuration cfg=new Configuration().configure(); SchemaExport se=new SchemaExport(cfg); se.create(true, true); } @Test public void save(){ Session session=HibernateUtils.getSession(); Transaction ts=session.beginTransaction(); //在单向的多对一中,要先添加少的一端 Dept dept=new Dept(); dept.setDeptName("财务部"); session.save(dept); Employee emp=new Employee(); emp.setEmpName("zhangsan"); emp.setHiredate(new Date()); emp.setDept(dept); session.save(emp); ts.commit(); HibernateUtils.close(session); } @Test public void get(){ Session session=HibernateUtils.getSession(); Transaction ts=session.beginTransaction(); Employee emp=(Employee)session.get(Employee.class, 1); System.out.println(emp.getEmpName()+"---->"+emp.getHiredate()); Hibernate.initialize(emp.getDept()); //Dept dept=emp.getDept(); //System.out.println(dept.getId()+"-->"+dept.getDeptName()); ts.commit(); HibernateUtils.close(session); } }
package util; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtils { private static SessionFactory factory; static{ factory=new Configuration().configure().buildSessionFactory(); } public static SessionFactory getFactory(){ return factory; } public static Session getSession(){ return factory.openSession(); } public static void close(Session session){ if(session!=null){ session.close(); } } }