Hibernate笔记之6数据关联一对多

Hibernate笔记之6数据关联一对多

Hibernate数据关联是在Hibernate容器映射技术之上发展起来的。
Hibernate数据关联分为如下三种:
一对一(1:1)一个人拥有唯一身份证号
一对多(1:N)一个部门有很多员工
多对多(M:N)一个学生可以选很多课程,一门课程也可以有多个学生
一对多关系很常见,例如班级与学生的关系就是典型的一对多的关系。在实际编写程序时,
一对多关系有两种实现方式:单向关联和双向关联。
单向的一对多关系只需要在一方进行映射配置,而双向的一对多需要在关联的双方进行映射配置.
下面以Group(班级)和Student(学生)为例讲解如何配置一对多的关系。
单向关联:

单向的一对多关系只需要在一方进行映射配置,所以我们只配置Group的映射文件: <hibernate-mapping>
    <class name="hibernate.PO.Group" table="t_group" lazy="true">
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="increment"/>                 
        </id>
        <!-- insert属性表示被映射的字段是否出现在SQL的INSERT语句中 -->
        <property name="name" type="java.lang.String" update="true" insert="true">
            <column name="name" length="20" />
        </property>
        
        <!-- set元素描述的字段对应的类型为java.util.Set类型。
            inverse用于表示双向关联中的被动一端。inverse的值
            为false的一方负责维护关联关系。默认是false。
            sort排序关系,其可选值为:unsorted(不排序)。
                                  natural(自然排序)。
                                  comparatorClass(由某个实现了java.util.comparator接口的类型指定排序算法。)
            <key>子元素的column属性指定关联表(t_student表)的外键。
       -->
        <set name="students"
             table="t_student"
             lazy="true"
             inverse="false"
             cascade="all"
             sort="unsorted">
        <key column="ID"/>
        <one-to-many class="hibernate.PO.TStudent"/>        
        </set>
    </class>
</hibernate-mapping>

双向关联:

如果要设置一对多双向关联关系,那么还需要在“多”方的映射文件中使用<many-to-one>标记。
例如,在Group与Student一对多的双向关联中,除了Group的映射文件外还需要在Student的映射文件中加入如下代码:
   <many-to-one name="group"
                     class="Group"
                     cascade="none"
                     outer-join="auto"
                     update="true"
                     insert="true"
                     column="ID" />
inert和update设定是否对column属性指定的关联字段进行insert和update操作。
也就是说被映射的字段是否出现在SQL的insert或update语句中。
此外将Group.hbm.xml中<set>元素的inverse设置为true.
还是举个实际例子吧:
先是数据库创建脚本:
-- 删除表
DROP TABLE person ;
DROP TABLE address ;

CREATE TABLE person
(
pid VARCHAR(32) NOT NULL PRIMARY KEY ,
name VARCHAR(20) NOT NULL ,
age INT
) ;

CREATE TABLE address
(
aid VARCHAR(32) NOT NULL PRIMARY KEY ,
name VARCHAR(50) NOT NULL ,
zipcode VARCHAR(10) NOT NULL ,
pid VARCHAR(32) ,
FOREIGN KEY (pid) REFERENCES person(pid) ON DELETE CASCADE
) ;
*****************************************************************
然后编写POJO类:
package wjr.hibernate.demo23_26.associated1N;

import java.util.Set;

public class Person {
private String pid;
private String name;
private int age;
private Set address;
。。。。。getter和setter方法。。。。
}
package wjr.hibernate.demo23_26.associated1N;

public class Address {
private String aid;
private String name;
private String zipcode;
private String pid;
private Person person;
。。。。。getter和setter方法。。。。
}
******************************************************************
生成和修改配置文件:
<class name="wjr.hibernate.demo23_26.associated1N.Person" table="person" catalog="test">
        <id name="pid" type="java.lang.String">
            <column name="pid" length="32" />
            <generator class="uuid.hex"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="20" not-null="true" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="age" />
        </property>
        <set name="address" inverse="true" cascade="all">
            <key>
                <column name="pid" length="32" unique="true" />
            </key>
            <one-to-many class="wjr.hibernate.demo23_26.associated1N.Address" />
        </set><!--inverse="true"表示自动反转关联,也就是在插入数据时能自动将关联id插入数据库,
          如果inverse="false",则在插入数据时,先插入,然后再更新关联数据,这样就多了
          几条更新语句(插入几条记录就多几条更新语句),效率降低了-->
        </class>
·····················
<class name="wjr.hibernate.demo23_26.associated1N.Address" table="address" catalog="test">
        <id name="aid" type="java.lang.String">
            <column name="aid" length="32" />
            <generator class="uuid.hex"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name" length="50" not-null="true" />
        </property>
        <property name="zipcode" type="java.lang.String">
            <column name="zipcode" length="10" not-null="true" />
        </property>
        <many-to-one name="person" class="wjr.hibernate.demo23_26.associated1N.Person" >
            <column name="pid" length="32" />
        </many-to-one>
    </class>
*********************************************************
编写操作类:
package wjr.hibernate.demo23_26.associated1N;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

public class OperateTest {
Session session = null;
public OperateTest()
{
  session = new Configuration().configure().buildSessionFactory().openSession() ;
}
public void insert(Person person)
{
  this.session.save(person);
  this.session.beginTransaction().commit();
}
public void update(Person person)
{
  this.session.update(person);
  this.session.beginTransaction().commit();
}
public void delete(String id)
{
  String hql ="delete from Person where pid = ?";
  Query q = this.session.createQuery(hql);
  q.setString(0, id);
  q.executeUpdate();
  this.session.beginTransaction().commit();
  }

public Person queryByName(String name) {
  Person p = null;
  String hql = "FROM Person AS p WHERE p.name=?";
  Query q = this.session.createQuery(hql);
  q.setString(0, name);
  List all = q.list();
  if (all.size() > 0) {
   p = (Person) all.get(0);
  }
  return p;
}
}
*******************************************************************
最后写测试类:
package wjr.hibernate.demo23_26.associated1N;

public class TestRun {

public static void main(String[] args) {
  //测试插入
//  OperateTest test = new OperateTest();
//  Person person = new Person();
//  person.setName("wjr");
//  person.setAge(25);
//  //地址
//  Address address = new Address();
//  address.setName("双流");
//  address.setPerson(person);
//  address.setZipcode("610021");
//  
//  Set set = new TreeSet();
//  set.add(address);
//  person.setAddress(set);
//  test.insert(person);
  //测试update
  OperateTest test = new OperateTest();
  Person person = test.queryByName("wjr");
  //增加地址
  Address address = new Address();
  address.setName("人民南路");
  address.setPerson(person);
  address.setZipcode("610041");
  person.getAddress().add(address);
  
  test.update(person);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值