hibernate多表联查

创建多表联查

一对一

public class Teacher{
    private int id;
    private String  name;
    private  Room room;

}

public  class  Room{
    private int id;
    private String  name;
    private Teacher teacher;

}

配置ORM映射文件

在有外键的一方配置

<class name="Room" table="room">
    <id name="id">
        <generator class="native"></generator>
    </1id>

    <property name="name"></property>
<!--
一对一是特虚的多对
name:属性名称
class:属性类型
column:关联本属性的外键字段
-->
<many-to-one name="teacher" class="Teacher"  column="t_id" update="true"></many-to-one>

</class>

一对多

/**
创建实体类在一的一方添加set或者list集合,推荐使用set,因为使用的时候需要在集合中添加元素,所以在声明的时候直接进行初始化操作
*/

public class Room{
    private  int  id;
    private  String name;
    private  Teacher teacher;
    private  Set<student> students = new  HasSet<>();
 
}

/**
在一的一方添加另一方的类型属性

*/
public class Student{
    private int id;
    private String name;
    private Room  room;

}

一对多

配置ORM映射文件

    无论在一的一方还是在多的一方都需要设置外键,所以两边的外键名称

必须一致

<hibernate-mapping package="com.zhiyou.model">
    <class name="Room"  table="room">
    <id name="id">
        <genernate class="native"></generator>
    </id>
    <property name="name"></property>
<!--
name:属性名称
key:关联的外键名称
one-to-many中的class:集合中的元素类型
-->
<set name="students">
    <key column="r_id">
    <one-to-many class="Student">
</set>
</class>
</hibernate-mapping>

多对多

在两方都定义对方类型的set集合并初始化

public class Student{

       private int  id;
       private String name;
       private Set<Course> course = new HashSet<>();
}

public class Course{
        private int id;
        private String name;
        private Set<Student> students = new HashSet<>();

}

配置ORM映射文件

<hibernate-mapping package="com.zhiyou.model">
    <class name="Course" table="course">
    <id name="id">
    <generator class="native"></generator>
    </id>
    <property name="name"></property>
<!--
name:属性名称
table:多对多关系要生成的第三张表。table为第三张表名
key:当前类型在第三张表中的外键字段名称
many-to-many:多对多,表示另一方的设置内容
class:另一方的类型
column:另一方在第三张表中的字段名称
-->
<set name="students" table="sc_table">
    <key column="c_id"></key>
    <many-to-many class="Student" column="s_id"/>
</set>
</class>
</hibernate-mapping>

注解

Hibernate提供了Hibernate  Annotations扩展包,它可以替换复杂的hbm.xml文件

( Annotations扩展包是hibernate-annotation-3.4.0GA.zip)

使得Hibernate程序的开发大大的简化。利用注解后,可不用定义持久化类型对应的*.hbm.xml,

而直接以注解方式写入持久化类的实现中。

@Entity  将一个类声明为一个持久化类

@Id  声明了持久化类的标识属性(相当于数据表的主键)

@GeneratedValue  定义标识属性值的生成策略

@Table  为持久化类映射指定表(table)

@UniqueConstraint  定义表的唯一约束

@Lob 表示属性将被持久化为Blob或者Clob类型

@Column 将属性映射到列

@Transient  忽略这些字段和属性,不用持久化到数据库。

使用:

  1.  直接在实体类中添加对应的注解,不需要创建对应的映射文件 
  2. 在hibernate.cfg.xml中通过mapper标签的class属性加载对应的实体类文件
<!--添加映射文件-->
<mapping  class="com.zhiyou.modle.Student"/>
<mapping  class="com.zhiyou.modle.Room"/>
<mapping  class="com.zhiyou.modle.Teacher"/>
<mapping  class="com.zhiyou.modle.Course"/>

注解配置对象关联关系(一对一)

@Entity  
@Table(name="room")
public  class Room{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int  id;
    @Column(name="name")
    private String name;
    @OneToOne
    @JoinColumn(name="t_id")
    private Teacher  teacher;
}
//mappedBy表示由teacher对象维护关联
@Entity
@Table(name="teacher")
public class Teacher{

@Id
@GeneratedValue(strategy="GenerationType.IDENTITY")
private int id;
@Column
private String name;
@OneToOne(mappedBy="teacher")
private Room room;
}

配置多对一关系

//JoinColumn指表中表示关联关系的外键字段
@Entity
@Table(name="student")
public class Student{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int  id;
    @Column
    private String name;
    @ManyToOne
    @JoinColumn(name="r_id")
    private Room room;
}

配置一对多关系

@Entity
@Table(name="room")
public class Room{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    @Column(name="name")
    private String name;
    @OneToMany(mappedBy="room")
    private Set<Student> students


}

注解配置多对多关系

  1. fetch加载策略  急加载
  2. joinTable 多对多中第三张表的表名
  3. joinColumn  student表和第三张表外键关联关系
  4. innerseJoinColumns:course表和第三张表的外键关联关系
@Entity
@Table(name="student")
public class Student{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column
private String name;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="sc_table",
joinColumns=@JoinColumn(name="s_id",referencedColumnName="id"),inverseJoinCoumns=@JoinColumn(name="c_id",referencedColumnName="id")
)
private Set<Course> course = new HashSet<>();
}

mappedBy将控制权交给学生(配置的学生类中关联属性名称)

@Entity
@Table(name="course")
public class Course{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    @Column
    private String name;
    @ManyToMany(mappedBy="courses")
    private Set<Student> students = new HashSet<>();


}

mappedBy的作用

mappedBy的意思就是“被映射”,即mappedBy这方不用管关联关系,关联关系交给另一方处理

规律:凡是双向关联,mapped必设,因为根本都没必要在2个表中都存在一个外键关联,在数据库中只要定义一边就可以了 只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;  mappedBy标签一定是定义在the owned side(被拥有方的),他指向the owning side(拥有方);

fetch策略

@OneToMany(fetch=FetchType.EAGER) @Fetch(value=FetchMode.SUBSELECT) 两者都是设定关联对象的加载策略。前者是JPA标准的通用加载策略注解属性。 后者是Hibernate自有加载策略注解属性。

FetchType可选值

FetchType.LAZY: 懒加载,在访问关联对象的时候加载(即从数据库读入内存) FetchType.EAGER:立刻加载,在查询主对象的时候同时加载关联对象。

FetchMode可选值

@Fetch(FetchMode.JOIN): 始终立刻加载,使用外连(outer join)查询的同时加载关联对象,忽略FetchType.LAZY设定。 join对HQL不生效 @Fetch(FetchMode.SELECT) :默认懒加载(除非设定关联属性lazy=false),当访问每一个关联对象时加载该对象,会累计产生N+1条sql语句 @Fetch(FetchMode.SUBSELECT)  默认懒加载(除非设定关联属性lazy=false),在访问第一个关联对象时加载所有的关联对象。会累计产生两条sql语句。且FetchType设定有效

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值