Hibernate入门教程
2015-06-27 18:18
295 查看
Hibernate入门教程 第三章
Hibernate一对多、多对一、单边及双边配置
我们上篇文章主要讲了Hibernate的一对一的配置(2种情况),这篇文章主要说一下Hibernate的一对多和多对一的双边配置情况,如果我们只配置其中的一边关系,比如,我们只在一方配置关系那么以上情况就变为单边的一对多,如果我们只配置多方,那么就变成了单边多对一。所以以上我们说了3中情况,其实是差不多的,所以这里我们放到一起讲。很多人可能有的时候搞不清什么时候到底是单边还是双边,其实我们碰到具体的情况我们就知道了,比如学生和班级,这既是一对多、又是多对一,所以我们应该配置双边的。比如用户和邮箱,一个用户有多个邮箱,我们应该配置成单边的一对多的关系。再比如论文系统,多个文章对应一个类型,我们应该配置成单边的多对一关系。当然以上说的一对多和多对一你都可以配成双边的,主要看需求。这里大家只要搞清楚有这几种情况就好了。我们下面开始说重点。
预备知识;
inverse的设置,既然关系设计到单边和双边就涉及到关系到底由一方来维护,还是由多方来维护,Hibernate中默认是由多方来维护;比如学生和班级,学生的多方、班级是单方,那么默认由学生来维护他们之间的关系。
一、配置文件
1、学生类:
3、班级类
1、插入数据
s1.setClass100(c);我们看到这里由Student来维护关系的,如果我们想让Class来维护关系应该这么做呢,如下:
在班级的配置文件中加上这一句
<set name="students" inverse="false"> 既不是由对方来控制关系那么就是自已来控制关系啦
那么我们fun1改写为如下:
2、查询
3、删除与更新简单,没有设置级联的时候要考虑约束
三、对应相应的一对多和多对一的单边配置,只要删除对应的关系就可以了,这里不再啰嗦
说明:比如一对多的单边关系,则关系维护就有一方维护,比如本来中,我们删除Student中Class和相关的配置文件中的配置。现在的关系是一个班级对应多个学生这样的一对多的单边关系。那么这个时候关系就有一方既班级来维护,Hibernate中如果双边关系都在,则默认是由多方维护关系,如果是单边的,那么谁在谁维护关系,在此说明!
Hibernate一对多、多对一、单边及双边配置
我们上篇文章主要讲了Hibernate的一对一的配置(2种情况),这篇文章主要说一下Hibernate的一对多和多对一的双边配置情况,如果我们只配置其中的一边关系,比如,我们只在一方配置关系那么以上情况就变为单边的一对多,如果我们只配置多方,那么就变成了单边多对一。所以以上我们说了3中情况,其实是差不多的,所以这里我们放到一起讲。很多人可能有的时候搞不清什么时候到底是单边还是双边,其实我们碰到具体的情况我们就知道了,比如学生和班级,这既是一对多、又是多对一,所以我们应该配置双边的。比如用户和邮箱,一个用户有多个邮箱,我们应该配置成单边的一对多的关系。再比如论文系统,多个文章对应一个类型,我们应该配置成单边的多对一关系。当然以上说的一对多和多对一你都可以配成双边的,主要看需求。这里大家只要搞清楚有这几种情况就好了。我们下面开始说重点。
预备知识;
inverse的设置,既然关系设计到单边和双边就涉及到关系到底由一方来维护,还是由多方来维护,Hibernate中默认是由多方来维护;比如学生和班级,学生的多方、班级是单方,那么默认由学生来维护他们之间的关系。
一、配置文件
1、学生类:
public class Student100 implements java.io.Serializable { // Fields private Integer sno; private Class100 class100; private String name; // Constructors /** default constructor */ public Student100() { } /** minimal constructor */ public Student100(Integer sno) { this.sno = sno; } /** full constructor */ public Student100(Integer sno, Class100 class100, String name) { this.sno = sno; this.class100 = class100; this.name = name; } // Property accessors public Integer getSno() { return this.sno; } public void setSno(Integer sno) { this.sno = sno; } public Class100 getClass100() { return this.class100; } public void setClass100(Class100 class100) { this.class100 = class100; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student100 [class100=" + class100 + ", name=" + name + ", sno=" + sno + "]"; } }2、学生配置文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.sunny.entity100.Student100" table="student100" catalog="test100"> <id name="sno" type="java.lang.Integer"> <column name="sno" /> <generator class="identity"></generator> </id> <property name="name" type="java.lang.String"> <column name="name" length="20" /> </property> <many-to-one name="class100" class="com.sunny.entity100.Class100"> <column name="class_id" /><!-- Student100表中将会生成一个外键class_id 引用Class100中的id --> </many-to-one> </class> </hibernate-mapping>
3、班级类
public class Class100 implements java.io.Serializable { // Fields private Integer id; private String name; private Set students = new HashSet(); // Constructors /** default constructor */ public Class100() { } /** minimal constructor */ public Class100(Integer id) { this.id = id; } /** full constructor */ public Class100(Integer id, String name, Set students) { this.id = id; this.name = name; this.students = students; } // Property accessors public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public Set getStudents() { return students; } public void setStudents(Set students) { this.students = students; } }4、班级配置文件
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.sunny.entity100.Class100" table="class100" catalog="test100"> <id name="id" type="java.lang.Integer"> <column name="id" /> <generator class="identity"></generator> </id> <property name="name" type="java.lang.String"> <column name="name" length="20" /> </property> <set name="students"><!-- lazy默认为true既打开延时加载 --> <key> <column name="class_id" /><!-- 定义集合所对应的数据库表的外键,class_id位student表的外键 --> </key> <one-to-many class="com.sunny.entity100.Student100" /> </set> </class> </hibernate-mapping>二、数据库操作
1、插入数据
public static void fun1(){ Session session = HibernateSessionFactory.getSession(); session.beginTransaction(); Student100 s1 = new Student100(); Class100 c = new Class100(); c.setName("三年二班"); s1.setName("apache"); s1.setClass100(c);//默认是多方维护关系,既关系由Student来维护 session.save(c); session.save(s1); session.getTransaction().commit(); session.close(); }
s1.setClass100(c);我们看到这里由Student来维护关系的,如果我们想让Class来维护关系应该这么做呢,如下:
在班级的配置文件中加上这一句
<set name="students" inverse="false"> 既不是由对方来控制关系那么就是自已来控制关系啦
那么我们fun1改写为如下:
public static void fun1_1(){ Session session = HibernateSessionFactory.getSession(); session.beginTransaction(); Student100 s1 = new Student100(); s1.setName("apache"); Class100 c = new Class100(); c.setName("三年二班"); c.getStudents().add(s1);//Class维护关系 session.save(s1); session.save(c); session.getTransaction().commit(); session.close(); }补充:由于inverse一般设置在set上面,在一对一关系中,我们应该没有办法控制关系由谁来维护,一般是在有外键的哪一方维护的(个人认为)
2、查询
//查询 public static void fun2(){ Session session = HibernateSessionFactory.getSession(); session.beginTransaction(); Query query = session.createQuery("from Student100"); List<Student100> list = query.list(); for(Student100 stu:list){ System.out.println(stu.getClass100().getName()); } }产生n+1条sql语句,因为默认fetch为select
//fetch的使用 public static void fun4(){ Session session = HibernateSessionFactory.getSession(); session.beginTransaction(); Query query = session.createQuery("from Class100 c left join fetch c.students"); //Query query = session.createQuery("from Student100 s"); List<Class100> ss = query.list(); for(Class100 s : ss){ System.out.println(s); } }由于lazy设置为true(默认),所以我们要用fetch把学生从班级里抓取出来,当然也可以不抓取,那么当要用到学生信息时候,Hibernate会自动抓取
3、删除与更新简单,没有设置级联的时候要考虑约束
三、对应相应的一对多和多对一的单边配置,只要删除对应的关系就可以了,这里不再啰嗦
说明:比如一对多的单边关系,则关系维护就有一方维护,比如本来中,我们删除Student中Class和相关的配置文件中的配置。现在的关系是一个班级对应多个学生这样的一对多的单边关系。那么这个时候关系就有一方既班级来维护,Hibernate中如果双边关系都在,则默认是由多方维护关系,如果是单边的,那么谁在谁维护关系,在此说明!
相关文章推荐
- 虚拟机Linux----Ubuntu1204----设置固定Ip
- intellij系列ide配置
- 如何在iOS应用中使用自定义字体
- IntPtr介绍
- cos,sina,tan,cot
- Linux1.0内核中断体系的建立
- Android的Fragment中onActivityResult不被调用的解决方案(绝对管用)
- Multivariance Linear Regression练习
- Tomcat的配置
- [学习笔记—Objective-C]《Objective-C 程序设计 第6版》第四章 数据类型和表达式
- 实现有道词典功能的界面
- NSAttributedString.h文件翻译
- 特殊的IP地址详解
- (转)C++中的static关键字的总结
- 提取文件名(非查找文件)
- Kablink Team文档&资料
- setContentScaleFactor 设置图片的分辨率
- 7.12
- HTML Input中信息提示框,字颜色是灰色,当用户把焦点放在框中清空值
- 程序员如何看待实力与运气