一、一对一:
第一种情况:IdCard类的ID 既是主键又是外键
package dao.po; //人 public class Person { private int id; //ID private String name;//姓名 private IdCard idCard; //身份证(对象) }
package dao.po; //身份主类 public class IdCard{ private int id;//ID private String address;//地址 private Person person; //身份证的主人 }
<?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="dao.po"> <class name="Person"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="255" column="`name`"/> <!-- 这里做一对一映射 --> <!-- 没什么好说的,就是一 one-to-one --> <one-to-one name="idCard" ></one-to-one> </class> </hibernate-mapping>
<?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="dao.po"> <class name="IdCard" table="id_card"> <id name="id"> <!-- 注意: --> <!-- 本类的id 既是主键,又是外键 --> <!-- IdCard对象的是从对象, Person是主对象, 先有主,后有从. --> <generator class="foreign"> <!-- 此处的person是IdCard类的一个属性 --> <param name="property">person</param> </generator> </id> <property name="address" not-null="true" length="255" column="`address`"/> <!-- 此处的person是IdCard类的一个属性 --> <!-- constrained="true" 对生成的数据表产生约束,id_card表的id既是主键,又是外键 --> <!-- constrained="false" 表结构上没有约束, 取何值对对象关系没影响,只是对表结构有影响--> <one-to-one name="person" constrained="true"/> </class> </hibernate-mapping>
保存与查询:
package dao; import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import dao.po.IdCard; import dao.po.Person; public class One2One{ public static void main(final String[] args){ add(); final IdCard c1 = query(5); System.out.println(c1.getPerson().getName()); } //保存 public static void add(){ final Person p1 = new Person(); p1.setName("小明"); final IdCard c1 = new IdCard(); c1.setAddress("北京市海淀区上地"); p1.setIdCard(c1); //建立关联(不能少) c1.setPerson(p1); //建立关联(不能少) Session session = null; try{ session = HibernateUtil.getSeesion(); final Transaction tx = session.beginTransaction(); //session.save(p1); // session.save(c1); //身份证是从对象依赖于主对象, "身份证"依赖于"人", //保存 c1 , 也会自动保存 他依赖的p1,前题是c1 与p1要关联 tx.commit(); //SQL 如下: //Hibernate: insert into Person (`name`) values (?) //Hibernate: insert into id_card (`address`, id) values (?, ?) //虽然只执行了session.save(c1) , 但有两个insert }finally{ if (session != null){ session.close(); } } } //查询 身份证 public static IdCard query(final int id){ Session session = null; try{ session = HibernateUtil.getSeesion(); final IdCard c1 = (IdCard) session.get(IdCard.class, id); Hibernate.initialize(c1.getPerson()); return c1; //SQL 如下: //Hibernate: select idcard0_.id as id3_0_, idcard0_.`address` as address2_3_0_ from id_card idcard0_ where idcard0_.id=? //Hibernate: select person0_.id as id2_1_, person0_.`name` as name2_2_1_, idcard1_.id as id3_0_, idcard1_.`address` as address2_3_0_ from Person person0_ left outer join id_card idcard1_ on person0_.id=idcard1_.id where person0_.id=? //注意person表又连了id-card表 }finally{ if (session != null){ session.close(); } } } }
第二种情况:IdCard类的ID 只是主键, IdCard类多对一属性 person_id做 外键,指向Person类的主键。
这种情况有点像 多对一,关系如下图:
两个配置文件内容如下
二、多对多:
多对多由于在性能和操作都不大理想,所以使用很少。实际使用中最好转换为一对多的模型。Hibernate会为我们创建中间关联表,转换成两个一对多。
package dao.po; import java.util.Set; //学生类 public class Student{ private int id; private String name; private Set<Teacher> teachers; }
package dao.po; import java.util.Set; //老师类 public class Teacher{ private int id; private String name; private Set<Student> students; }
<?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="dao.po"> <class name="Student"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="255" column="`name`"/> <!-- name="teachers" 表示:Student类中有一个属性叫teachers (是Set集合)--> <!-- table="teacher_student" 表示:中间表表名叫teacher_student --> <set name="teachers" table="teacher_student"> <!-- column="student_id" 表示:中间表teacher_student的字段--> <!-- Student类的id与中间表teacher_student的字段student_id对应--> <key column="student_id"/> <!-- column="teacher_id" 表示:中间表teacher_student的字段--> <!-- class="Teacher" 表示:中间表teacher_student的字段teacher_id与 Teacher类的id对应--> <many-to-many class="Teacher" column="teacher_id"/> </set> </class> </hibernate-mapping>
<?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="dao.po"> <class name="Teacher"> <id name="id"> <generator class="native"/> </id> <property name="name" not-null="true" length="255" column="`name`"/> <set name="students" table="teacher_student"> <key column="teacher_id"/> <many-to-many class="Student" column="student_id"/> </set> </class> </hibernate-mapping>
保存操作:
package dao; import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.Transaction; import dao.po.Student; import dao.po.Teacher; public class Many2Many { public static void main(final String[] args){ add(); } //添加几个老师与学生 public static void add(){ final Teacher t1 = new Teacher(); t1.setName("语文老师"); final Teacher t2 = new Teacher(); t2.setName("数学老师"); final Student s1 = new Student(); s1.setName("学生小明"); final Student s2 = new Student(); s2.setName("学生小红"); //final Set<Teacher> set_t = new HashSet<Teacher>(); //set_t.add(t1); //set_t.add(t2); final Set<Student> set_s = new HashSet<Student>(); set_s.add(s1); set_s.add(s2); //给老师set 学生 t1.setStudents(set_s); //建立关联,只在一方面建立关联就行了, 不可给学生set()了老师,再老师set()了学生 t2.setStudents(set_s); //建立关联,只在一方面建立关联就行了, 不可给学生建了关联,再老师建关联 //给学生set老师,不可以再做 Session session = null; try{ session = HibernateUtil.getSeesion(); final Transaction tx = session.beginTransaction(); session.save(t1); session.save(t2); session.save(s1); session.save(s2); tx.commit(); }finally{ if (session != null){ session.close(); } } } } // 中间表teacher_student 表结构如下 : //| teacher_student | CREATE TABLE `teacher_student` ( // `teacher_id` int(11) NOT NULL, // `student_id` int(11) NOT NULL, // PRIMARY KEY (`student_id`,`teacher_id`), // KEY `FK2E2EF2DE4BF3A147` (`teacher_id`), // KEY `FK2E2EF2DE3B5856A7` (`student_id`), // CONSTRAINT `FK2E2EF2DE3B5856A7` FOREIGN KEY (`student_id`) REFERENCES `student //` (`id`), // CONSTRAINT `FK2E2EF2DE4BF3A147` FOREIGN KEY (`teacher_id`) REFERENCES `teacher //` (`id`) //) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
时间: 2024-08-05 16:46:39