Hibernate中的一对多单向关联

来源:互联网 发布:孙真人知柏地黄丸好吗 编辑:程序博客网 时间:2024/06/14 03:24

Hibernate中的一对多单向关联

意思是:一方可以看到多方,多方看不到一方

实例:国家与城市——国家为1,城市为n

一、基本概念

域属性:对象自身的属性

关联属性:关联关系的属性

有Country(国家)和City(城市)两个实体

在国家实体中,countryName、countryID为域属性,citys为关联属性

这里写图片描述

关联方向——分为单向和双向

单向关联:只在一方把另一方作为关联属性,即只有一个实体对象可以加载和访问对方

Country中有citys,而City中没有country;

双向关联:彼此把对方设为关联属性,彼此都可以加载和访问

Country中有citys,City中也有country;

关联关系的维护:

关联关系在Java代码上的维护:

这里写图片描述

关联关系在数据库上的维护:

本质上是对外键值的维护,当少的一方维护关系时

这里写图片描述

当多的一方维护关系时:

这里写图片描述
总结一下就是session.save(1)维护外键关系的是update语句,session.save(n)维护外键关系的是insert语句


牢记一点,Java代码谁在维护关联关系,session就save谁

1)实体类(1、Country )

package com.hibernate.beans;import java.util.HashSet;import java.util.Set;public class Country {    //域属性    private Integer countryId;    private String countryName;    //关联属性    private Set<City> citys;    public Country() {        citys = new HashSet<City>();    }    public Country(String countryName) {        this();        this.countryName = countryName;    }    public Integer getCountryId() {        return countryId;    }    public void setCountryId(Integer countryId) {        this.countryId = countryId;    }    public String getCountryName() {        return countryName;    }    public void setCountryName(String countryName) {        this.countryName = countryName;    }    @Override    public String toString() {        return "Country [countryId=" + countryId + ", countryName="                + countryName +  "]";    }    public Set<City> getCitys() {        return citys;    }    public void setCitys(Set<City> citys) {        this.citys = citys;    }}

2)实体类(2、City)

package com.hibernate.beans;public class City {    private Integer cityId;    private String cityName;    public City() {    }    public City(String cityName) {        this.cityName = cityName;    }    public Integer getCityId() {        return cityId;    }    public void setCityId(Integer cityId) {        this.cityId = cityId;    }    public String getCityName() {        return cityName;    }    public void setCityName(String cityName) {        this.cityName = cityName;    }    @Override    public String toString() {        return "City [cityId=" + cityId + ", cityName=" + cityName                +  "]";    }}

3)映射文件(Country.hbm.xml)

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.hibernate.beans">     <class name="Country" table="t_country">        <!-- 域属性的映射 -->        <id name="countryId" column="t_countryId">            <!-- 主键生成策略 -->            <generator class="native"></generator>        </id>        <property name="countryName" column="t_countryName"></property>        <!-- 关联属性的映射 -->        <set name="citys" cascade="save-update"><!-- save-update级联保存 -->            <!-- 一方主键对应在多方表的外键名 -->            <key column="t_countryId"></key>            <!-- 多方的类型 -->            <one-to-many class="City"/>        </set>     </class> </hibernate-mapping>

4)映射文件(City.hbm.xml)

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.hibernate.beans">     <class name="City" table="t_city">        <id name="cityId" column="t_cityId">            <!-- 主键生成策略 -->            <generator class="native"></generator>        </id>        <property name="cityName" column="t_cityName"></property>     </class> </hibernate-mapping>

5)主映射文件(Hibernate.hbm.xml)

测试方法:

public void test() {        // 获取连接        Session session = HbnUtils.getSession();        try {            // 开启事务            session.beginTransaction();            Country country = new Country("CN");            City city0 = new City("南昌");            City city1 = new City("武汉");            City city2 = new City("长沙");            country.getCitys().add(city0);            country.getCitys().add(city1);            country.getCitys().add(city2);            // 执行业务            session.save(country);            // 提交事务            session.getTransaction().commit();        } catch (Exception e) {            e.printStackTrace();            // 回滚            session.getTransaction().rollback();        }    }

分析运行过程

从控制台日志可以看出Hibernate运行过程

Hibernate:     insert     into        t_country        (t_countryName)     values        (?)Hibernate:     insert     into        t_city        (t_cityName)     values        (?)Hibernate:     insert     into        t_city        (t_cityName)     values        (?)Hibernate:     insert     into        t_city        (t_cityName)     values        (?)Hibernate:     update        t_city     set        t_countryId=?     where        t_cityId=?Hibernate:     update        t_city     set        t_countryId=?     where        t_cityId=?Hibernate:     update        t_city     set        t_countryId=?     where        t_cityId=?

首先保存了City对象除了外键以外的所有的字段,然后保存Country对象的所有字段,最后根据Country的id去更新City的外键字段

控制台打印顺序并不是Hibernate的执行顺序,执行顺序参考官方文档


如有疑问,欢迎入群讨论:511906138

1 0