多对一单向关联,只能从多的一端导航到一的一端
实体类
package org.leadfar.hibernate.model; public class ContactPerson { private int id; private String name; private Group group; public ContactPerson() { // TODO Auto-generated constructor stub } public ContactPerson(String name) { // TODO Auto-generated constructor stub this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Group getGroup() { return group; } public void setGroup(Group group) { this.group = group; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.hibernate.auction"> <!-- name为实体类 table为映射到数据库中的表 lazy默认为true 延迟发出select语句,直到真正用到对象的属性(非id属性)--> <class name="org.leadfar.hibernate.model.ContactPerson" table="t_person" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> <!--多对一关联映射配置--> <many-to-one name="group" column="gid"></many-to-one> </class> </hibernate-mapping>
package org.leadfar.hibernate.model; public class Group { private int id; private String name; public Group() { // TODO Auto-generated constructor stub } public Group(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="org.hibernate.auction"> <!-- name为实体类 table为映射到数据库中的表 lazy默认为true 延迟发出select语句,直到真正用到对象的属性(非id属性)--> <class name="org.leadfar.hibernate.model.Group" table="t_group" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
Hibernate配置文件
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">true</property> <!-- create-drop 测试用,用完即删 --> <!-- create 如果没有则创建,有则替换 --> <!-- validate 校验,如果没有表,则报错 --> <!-- update,没有则创建,有且数据有变化,则更新,没有则什么都不做 --> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="org/leadfar/hibernate/model/ContactPerson.hbm.xml"></mapping> <mapping resource="org/leadfar/hibernate/model/Group.hbm.xml"></mapping> </session-factory> </hibernate-configuration>
测试
package org.leadfar.hibernate.model; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test_Many2One_01 extends TestCase { //多对一单向关联 public void testSave_01() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory //buildSessionFactory的时候会自动创建数据库表 SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session session = sfactory.openSession(); try { //开启事务 session.beginTransaction(); ContactPerson cp1 = new ContactPerson("张学友"); session.save(cp1); ContactPerson cp2 = new ContactPerson("郑伊健"); session.save(cp2); ContactPerson cp3 = new ContactPerson("郭富城"); session.save(cp3); Group g1 = new Group("朋友"); session.save(g1); Group g2 = new Group("商务"); session.save(g2); Group g3 = new Group("陌生人"); session.save(g3); //发出了多余的update语句! 因为cp1 cp2 cp3被save后都变为持久化对象,当属性改变时hibernate会自动发出update语句 cp1.setGroup(g1); cp2.setGroup(g2); cp3.setGroup(g3); //提交事务 session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); //出现异常,回滚事务 session.getTransaction().rollback(); } finally { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } //避免多余的update语句发出 //先建立一的一端,再建立多的一端,避免不合理的创建导致hibernate发出多余的update语句 public void testSave_02() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory //buildSessionFactory的时候会自动创建数据库表 SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session session = sfactory.openSession(); try { //开启事务 session.beginTransaction(); Group g1 = new Group("朋友"); session.save(g1); Group g2 = new Group("商务"); session.save(g2); Group g3 = new Group("陌生人"); session.save(g3); ContactPerson cp1 = new ContactPerson("张学友"); cp1.setGroup(g1); session.save(cp1); ContactPerson cp2 = new ContactPerson("郑伊健"); cp2.setGroup(g2); session.save(cp2); ContactPerson cp3 = new ContactPerson("郭富城"); cp3.setGroup(g3); session.save(cp3); //提交事务 session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); //出现异常,回滚事务 session.getTransaction().rollback(); } finally { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } public void testSave_03() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory //buildSessionFactory的时候会自动创建数据库表 SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session session = sfactory.openSession(); try { //开启事务 session.beginTransaction(); //模拟页面提交用户并要求设置到某个组(由Struts2完成) Group g4 = new Group(); g4.setId(3);//设置到第3个组 ContactPerson cp4 = new ContactPerson("刘德华"); cp4.setGroup(g4); session.save(cp4); //提交事务 session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); //出现异常,回滚事务 session.getTransaction().rollback(); } finally { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } //仅仅是获取对象为了建立关联,使用load加载对象,hibernate不用发出select语句 public void testSave_04() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory //buildSessionFactory的时候会自动创建数据库表 SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session session = sfactory.openSession(); try { //开启事务 session.beginTransaction(); ContactPerson cp4 = new ContactPerson("路人丙"); cp4.setGroup((Group)session.load(Group.class, 1)); //仅仅是为了建立对象间的关联关系,没有使用到非id属性,hibernate不会发出查询语句 //这就是load方法的经典之处! session.save(cp4);//瞬时对象--》持久化对象,发出insert语句 //提交事务 session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); //出现异常,回滚事务 session.getTransaction().rollback(); } finally { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } //内存中重建对象之间的关联(hibernate底层是如何完成的呢?利用引用关系?反射?) public void testLoad_01() throws Exception { //默认读取类路径根目录下的hibernate.cfg.xml配置文件 Configuration cfg = new Configuration().configure(); //创建SessionFactory //buildSessionFactory的时候会自动创建数据库表 SessionFactory sfactory = cfg.buildSessionFactory(); //创建Hibernate Session Session session = sfactory.openSession(); try { //开启事务 session.beginTransaction(); ContactPerson cp1 = (ContactPerson)session.load(ContactPerson.class, 1); System.out.println(cp1.getId()); System.out.println(cp1.getName());//hibernate:select t_person System.out.println(cp1.getGroup().getName()); //hibernate:select t_group //提交事务 session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); //出现异常,回滚事务 session.getTransaction().rollback(); } finally { //关闭session session.close();//session关闭之后,user对象处于离线Detached状态 } } }