[键入文字]
s.close(); } }
同样在main方法中调用此方法,并开启控制台数据库库语言显示后。从控制台看出也只会查询一次,但是如果去掉注释后发现会查询两次。 接着,在此例的基础上修改成外键关联。
外键关联:从表的主键并不作为外键参考主表的主键,而是将其它字段作为外键参的主键。 其实在上例的基础上,我们只需要修改IdCard.hbm.xml配置文件即可,修改后的内容如下:
说明:由于采取了外键关联,所以这里的从表的主键将不再作为外键参考主表的主键,所以它会采取一般的方式
生成主键,即
4.多对多关系映射: 典型实例:一个学生可以有多个老师,同样一个老师可以有多个学生,对此设计如下: 学生studnet表: column Id Name teachers 老师teacher表: column Id Name studnets 在利用学生查到他所有的老师,我们一般会设计中间表,来查找,中间表用来把学生和老师关联,通过此表进行学生和老师之间的交互查找。 中间表teacher_student: column teacher_id studnet_id 复合主键 在数据库操作中,作以下说明:如果通过老师查找学生,过程:先通过teacher表查找到id,再到teacher_student表中以teacher.id==teacher_student.teacher_id为查询条件来查找studnent_id , 查找到studnet_id后,再以teacher_student.stucent_id==student.id为查询条件来查找所有学生的信息。 同样通过学生查老师,也是类似的过程。 >>步骤一、创建实体类Student、Teacher Student类内容如下:省略getXXX()、setXXX()方法。 package com.asm.hibernate.domain; import java.util.Set; public class Student { private int id; private String name; private Set - 16 - / 42 [键入文字] Teacher类内容如下:省略getXXX()、setXXX()方法。 package com.asm.hibernate.domain; import java.util.Set; public class Teacher { private int id; private String name; private Set >>步骤二、为两个实体创建配置文件(省略了前面的xml文档声明内容): Student.hbm.xml内容如下: package=\ 说明:这里重点说明最后的 (1)Student中Set类型的属性配置一个 (2)它的子元素 Teacher.hbm.xml内容如下: package=\ 由于和Student.hbm.xml是类似的,这里不作说明,这样也就建立起了双向的多对多关联。 要注意他们所依赖的中间表为teacher_student,所以这里的 >>步骤三、在主配置文件中关联实体配置文件:只需要增加如下内容: - 17 - / 42 [键入文字] >>步骤四、编写测试文件ManyToManyTest.java:省略导入的包。 package com.asm.hibernate.test; public class ManyToManyTest { public static void main(String[] args) { add(); } static void add() { Session s = null; Transaction tr = null; try { s = HibernateUtil.getSession(); tr = s.beginTransaction(); Teacher t1 = new Teacher(); t1.setName(\ Teacher t2 = new Teacher(); t2.setName(\ Student s1 = new Student(); s1.setName(\ Student s2 = new Student(); s2.setName(\ // 再增加如下内容进行测试: Set Set t1.setStudents(ss); t2.setStudents(ss); // s1.setTeachers(ts); // s2.setTeachers(ts); // 增加内容完 s.save(s1); s.save(s2); s.save(t1); s.save(t2); tr.commit(); } finally { if (s != null) s.close(); } } } 说明:注意以上注释掉的内容,如果去掉会出现异常。理解:加上增加的内容后再执行发现,在开启“数据 库显示”功能后,发现控制台中新增加了四条插入语句,且是插入到中间表teacher_student中,在此处相当于告诉了每个学生所关联到的老师,而如果在mysql客户端执行“show create table teacher_student”,观察它的表结构并结合“去掉注释的报错说明”,就容易理解到为什么不能有注释掉的内容。 另需要说明的是“多对多”在操作和性能方面都不太理想,所以它使用较少,一般我们会选择转换成“一对多”的模型,而Hiberante的“多对多” - 18 - / 42 [键入文字] 实现,可能也是转换成两个“一对多”来实现。 5.组件关系映射: 典型实例:每个人有不同的名字,或者多个人可以是同一个名字,对于这种现象可以是“一个一”或者“多对一”,这样会被设计成两张表来映射,而我们采用组件关系来映射就可以在一张表中映射实现。 具体过程如下: >>步骤一、编写实体文件Name.java 和People.java Name.java内容如下: 省略getXXX和setXXX() package com.asm.hibernate.domain; public class Name { private String firstName; private String secondName; } Name.java内容如下: 省略getXXX和setXXX() package com.asm.hibernate.domain; public class People { private int id; private Name name; } >>步骤二、编写配置文件People.hbm.xml 内容如下: package=\ 说明:尽管在上一步,说Name为实体配置文件,但这里并不为为它写配置文件,它实质相当于一个更一般化的属 性,且这个属性是在People的实体配置文件中用〈component〉元素来进行配置的,它的name属性是随意随的有意义的名字,而其子元素分别为Name类的属性值。 >>步骤三、在主配置文件中关联此实体配置文件: >>步骤四,编写测试类,内容如下:省略导入的包 package com.asm.hibernate.test; public class ComponentTest { public static void main(String[] args) { Name n = new Name(); n.setFirstName(\ n.setSecondName(\ People p = new People(); p.setName(n); add(p); } static void add(People p) { Session s = null; Transaction ts = null; - 19 - / 42 [键入文字] } } try { s = HibernateUtil.getSession(); ts = s.beginTransaction(); s.save(p); ts.commit(); } catch (HibernateException e) { if (ts != null) ts.rollback(); throw e; } finally { if (s != null) s.close(); } //说明:这种映射较简单,执行后可以查看下表结构。 6.总结关联关系: 在理解Hibernate如何处理这些对象之间的关联关系的底层细节时,考虑如何实现把这种关系保存到数据库,考虑如可检索出关联对象。 八、其它集合类型 说明:在前面我们已经使用过set集合类型,其实除了set外,在Hibernate中还有list、Bag、Map这三种集合类型。 1. list集合的使用: 在前面的“一对多的关系”,已经使用过 (2)需要修改原Department中的 (3)并注意测试类中相应的修改 (4)强调说明的是list查询时,具有顺序性,可以查看此项目下测试类的说明。 (5)再次强调,为了充分理解一些问题,我们可以查看执行后表结构,也可以注释掉一些内容查看异常情况,并学会解决异常。注意配置文件中相关配置的作用,并尝试探索底层实现。 2.bag集合的使用: 如果在实体类中使用了List类型的属性,而我们并不希望保证集合顺序(保证集合顺序会采用排序算法,因而会占一些CPU资源)可以在配置文件中使用 一般是和实体类中java.util.Map属性进行配合使用,而且使用情况较少。除非某些特殊要求。 总结使用规则:大部分情况下使用 (1)在实体类中集合只能被定义成接口而不能定义成具体类,因为集合会在运行时被替换成Hibernate的实现, 而事实上把实体类的属性定义成接口也更便于扩展及良好的维护。这里不防提出一个原则,“尽量用接口定义”。 (2)Hibernate操作List持久对象时,会用org.hibernate.collection.PersistentList重新实现List接口,操作 完成后会把这个实现类重新setXXX放置。具体请参见TheCollectionMapping项目下的OneToManyTest类说明。其它 - 20 - / 42 内容如下:
唯一不同的就是不保证集合顺序。 3.map集合的使用:
;想用java.util.List而不想保证顺序时,使用〈bag〉;