Hibernate教程之六一对多&多对一实现基于xml和注解

来源:互联网 发布:c语言主要应用有哪些 编辑:程序博客网 时间:2024/06/07 06:05

在上一篇博客中我们知道数据库的三种关系,那么这一篇就聊聊一对多的关系。
一对多的时候,需要明确外键究竟应该设置到那个表上,一般都是多的那个表中拥有一的表的主键来做外键。
人和银行卡,一个人有多张银行卡,多张卡属于一个人,那么这2个表就存在一对多和多对一的关系。
首先我们看看基于xml的实现:
Person类:

//人类--体现一对多,一个人有多张银行卡public class Person {    private int id;    private String name;    private int age;    //不需要通过索引操作集合    //private Set<BankCard> bankCards;//人拥有的所有银行卡    //需要索引操作集合    private List<BankCard> bankCards;//人拥有的所有银行卡    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 int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    /*public Set<BankCard> getBankCards() {        return bankCards;    }    public void setBankCards(Set<BankCard> bankCards) {        this.bankCards = bankCards;    }*/    public List<BankCard> getBankCards() {        return bankCards;    }    public void setBankCards(List<BankCard> bankCards) {        this.bankCards = bankCards;    }}

BankCard类:

//银行卡类,体现的是多对一,多张银行卡对应一个人public class BankCard {    private int id;    private String name;//银行    private String no;//银行卡号    private Person person;//卡所属的人    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 String getNo() {        return no;    }    public void setNo(String no) {        this.no = no;    }    public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }}

我这里才有的是list集合,所以配置的时候需要使用list标签并且还得维护一个索引字段,为了让Hibernate知道存储顺序的
Person类的映射文件:

<?xml version="1.0" encoding="UTF-8"?><!--文档说明,设置映射文件 --><!DOCTYPE hibernate-mapping        SYSTEM        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" ><!--映射标签 package:内部类的所在的包名 --><hibernate-mapping package="org.qf.onetomany">    <class name="Person" table="tb_person">        <!--id:主键,name:属性名称,column:字段名称 -->        <id name="id" column="id">            <generator class="identity" />        </id>        <!--配置属性对应的字段 -->        <property name="name" length="20" />        <property name="age" />        <!--属性为集合的配置 一对多 对多对 name:集合的属性名称 -->            <!--一对多是Set集合进行关联,无需去维护索引 -->        <!-- <set name="bankCards" lazy="false">            key标记的是集合中泛型类对应的外键字段 column:多的一方的外键(该外键必须来自当前的类的主键)            <key column="pid"></key>            存在一对多的关系 class:与哪个类存在一对多关系            <one-to-many class="BankCard" />        </set> -->        <!--使用List集合,通过索引控制  -->        <list name="bankCards">        <key column="pid"></key>        <index column="list_index"></index>        <one-to-many class="BankCard"/>        </list>    </class></hibernate-mapping>

BankCard类的映射文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping        SYSTEM        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" ><hibernate-mapping package="org.qf.onetomany">    <class name="BankCard" table="tb_bankcard">    <!--id:主键,name:属性名称,column:字段名称  -->        <id name="id" column="id">            <generator class="identity"/>        </id>        <!--配置属性对应的字段  -->        <property name="name" length="50" />        <property name="no" length="30" />        <!--在一对多和多对一中外键设置到多的一方          多对一,只需标记2个属性:        name:指明当前类的哪个属性存在多对一        column:指明外键的字段名称        cascade:级联设置,主要标记的书相关联的数据的修改操作:新增、修改、删除        当保存或删除当前对象时候,是否需要将有关联的对象也进行相同的操作        取值说明:   all:全部   delete:删除   save-update:保存或修改   fetch:抓取数据的策略   标记如果查询项关联的数据信息   取值:   1、join使用连接查询   2、 select单个查询  -->        <many-to-one name="person" column="pid" cascade="save-update" fetch="join"></many-to-one>    </class></hibernate-mapping>

以上就是一对多和多对一的关系配置,但是需要注意的是使用list集合,必须维护一个字段记录添加顺序,否则List集合无法使用
那么接下来,我们看看如何通过注解实现一对多和多对一呢?
注解主要用的就是@OneToMany和@ManyToOne
Person类:

//人类--体现一对多,一个人有多张银行卡@Entity@Table(name="tb_person")public class Person {    @Id//主键    @GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略    private int id;    @Column(length=20)    private String name;    private int age;    //不需要通过索引操作集合    //private Set<BankCard> bankCards;//人拥有的所有银行卡    //需要索引操作集合    @OneToMany(fetch=FetchType.EAGER,mappedBy="person",targetEntity=BankCard.class)//设置一对多,且立即加载    private List<BankCard> bankCards;//人拥有的所有银行卡    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 int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    /*public Set<BankCard> getBankCards() {        return bankCards;    }    public void setBankCards(Set<BankCard> bankCards) {        this.bankCards = bankCards;    }*/    public List<BankCard> getBankCards() {        return bankCards;    }    public void setBankCards(List<BankCard> bankCards) {        this.bankCards = bankCards;    }}

注意@OneToMany
体现一对多的映射,不会出现外键
常用属性:
mappedBy:关联的属性名称,就是存在多的一方中的本类的属性名称
targetEntity:集合中泛型类的Class类对象,其实就是多的类的Class
BankCard类:

//银行卡类,体现的是多对一,多张银行卡对应一个人@Entity@Table(name="tb_bc")public class BankCard {    @Id//主键    @GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略    private int id;    @Column(length=30)    private String name;//银行    @Column(length=30)    private String no;//银行卡号    @ManyToOne    @JoinColumn(name="pid")    private Person person;//卡所属的人    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 String getNo() {        return no;    }    public void setNo(String no) {        this.no = no;    }    public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }}

以上就是关于Hibernate中实现一对多和多对一的2种方式,xml和注解

原创粉丝点击