hibernate关系映射

一对多映射

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>

    <class name="com.jie.domain.TAddressProvince" table="t_address_province" schema="region">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="code" column="code"/>
        <property name="name" column="name"/>
        <!--一对多set
        name:当前类的属性名
        column:从表中的外键名
        foreign-key:主表中的被参照字段
        property-ref:主表中被参照字段的属性名
        class:从表的类
        -->
        <set name="citys" cascade="all">
            <key column="provinceCode" foreign-key="code" property-ref="code"></key>
            <one-to-many class="com.jie.domain.TAddressCity"></one-to-many>
        </set>
    </class>
</hibernate-mapping>

 domain类

package com.jie.domain;

import java.util.HashSet;
import java.util.Set;

public class TAddressProvince {
    private int id;
    private String code;
    private String name;
    private Set<TAddressCity>citys=new HashSet<>();

    public Set<TAddressCity> getCitys() {
        return citys;
    }

    public void setCitys(Set<TAddressCity> citys) {
        this.citys = citys;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        TAddressProvince that = (TAddressProvince) o;

        if (id != that.id) return false;
        if (code != null ? !code.equals(that.code) : that.code != null) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (code != null ? code.hashCode() : 0);
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }


}

这个其实就是在hibernate生成类的基础上添加属性 private Set<TAddressCity>citys=new HashSet<>();和其get、set方法。

util工具类

package com.jie.util;

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

public class HibernateUtil {
    static SessionFactory factory=null;
    static {
        //创建配置文件
        Configuration config=new Configuration();
        //读取配置文件
        config.configure("/hibernate.cfg.xml");
        //创建sessionFactory
        factory=config.buildSessionFactory();

    }
    //获取session
    public static Session getCurrentSession(){

        Session session=factory.openSession();
        return session;
    }
    //关闭session
    public static void closeSession(Session session){
        if (session!=null){
            session.close();
        }
    }
}

 test测试类

package com.jie;

import com.jie.domain.TAddressCity;
import com.jie.domain.TAddressProvince;
import com.jie.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.Test;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

//一对多
public class Test2 {
    //查询
    @Test
    public void getCityInfo(){
        Session session= HibernateUtil.getCurrentSession();
        List<TAddressProvince>provinces=session.createQuery("from TAddressProvince").list();
        HibernateUtil.closeSession(session);
    }
    //级联增加
    @Test
    public void sava(){
        Session session= HibernateUtil.getCurrentSession();
        session.beginTransaction();
        TAddressProvince province=new TAddressProvince();
        province.setName("JXQY");
        province.setCode("830000");
        Set<TAddressCity>cities=new HashSet<>();
        TAddressCity city1=new TAddressCity();
        city1.setName("QQ");
        city1.setCode("831000");
        TAddressCity city2=new TAddressCity();
        city2.setName("ZJSZ");
        city2.setCode("832000");
        cities.add(city1);
        cities.add(city2);
        province.setCitys(cities);
        session.save(province);
        session.getTransaction().commit();
        HibernateUtil.closeSession(session);
    }


    //级联修改
    @Test
    public void updata(){
        Session session= HibernateUtil.getCurrentSession();
        session.beginTransaction();
        TAddressProvince province=session.get(TAddressProvince.class,48);
        province.setName("JXQY123");
        Set cities=province.getCitys();
        Iterator iterator=cities.iterator();
        int i=100;
        while (iterator.hasNext()){
            TAddressCity city=(TAddressCity) iterator.next();
            city.setName("qq"+i++);
        }
        session.update(province);
        session.getTransaction().commit();
        HibernateUtil.closeSession(session);
    }

    //级联删除
    @Test
    public void delete(){
        Session session=HibernateUtil.getCurrentSession();
        session.beginTransaction();
        TAddressProvince province=session.get(TAddressProvince.class,48);
        session.delete(province);
        session.getTransaction().commit();

        HibernateUtil.closeSession(session);
    }
}

一对多映射总结:

分析SQL:
get方法:
1:通过one方获取many方,使用了延迟加载.
2:one方的many方的属性是一个集合,必须使用接口来声明.
3:不能通过if-null来判断one方是否有many方,只能通过size方法来判断.
4:必须在session关闭之前使用集合对象,否则报错:no session.
save方法:
由One方来维护外键关系,所以得发额外的两条SQL:
在保存对象的时候,因为对象的关系由one方维护,所以,在保存many方的时候,不会去修改外键的值;
只能在one方保存完成之后,由one方发送额外的update语句去修改many方的外键的值;

多对一映射

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>

    <class name="com.jie.domain.TAddressCity" table="t_address_city" schema="region">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="code" column="code"/>
        <property name="name" column="name"/>
        <!--<property name="provinceCode" column="provinceCode"/>-->
<!-- 多对一映射,关系有多方维护 name many方通过哪一个属性找到one方 column 生成外键的列名 -->
        <many-to-one name="province" class="com.jie.domain.TAddressProvince" property-ref="code" cascade="all">
            <column name="provinceCode"></column>
        </many-to-one>
    </class>
</hibernate-mapping>

domain类

package com.jie.domain;

public class TAddressCity {
    private int id;
    private String code;
    private String name;
//    private String provinceCode;
    private TAddressProvince province;
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public TAddressProvince getProvince() {
        return province;
    }

    public void setProvince(TAddressProvince province) {
        this.province = province;
    }
//    public String getProvinceCode() {
//        return provinceCode;
//    }
//
//    public void setProvinceCode(String provinceCode) {
//        this.provinceCode = provinceCode;
//    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        TAddressCity that = (TAddressCity) o;

        if (id != that.id) return false;
        if (code != null ? !code.equals(that.code) : that.code != null) return false;
        if (name != null ? !name.equals(that.name) : that.name != null) return false;
        //if (provinceCode != null ? !provinceCode.equals(that.provinceCode) : that.provinceCode != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (code != null ? code.hashCode() : 0);
        result = 31 * result + (name != null ? name.hashCode() : 0);
        //result = 31 * result + (provinceCode != null ? provinceCode.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "TAddressCity{" +
                "id=" + id +
                ", code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", province=" + province +
                '}';
    }
}

 注释掉与上级有关联的属性,添加上级对象属性,数据库对象的字段修改为允许null

总结:

分析get方法:
1:many方获取one方的时候,使用了延迟加载,生成了代理对象
2:可以使用if-null方式来判断,是否存在one方.
3:得到的one方,必须在session关闭之前实例化(获取非OID属性),否则报错:no session.
分析save方法:
先保存many方再保存one方,会产生额外的SQL,这些SQL是由于持久化对象(many)的脏数据造成的;

查询个别字段

​
package com.jie;

import com.jie.domain.TAddressProvince;
import com.jie.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.Test;

import java.util.List;

public class Test3 {

    @Test
    public void toTest(){

        Session session= HibernateUtil.getCurrentSession();
        //List<Object[]>lists=session.createSQLQuery("select id,name,code from TAddressProvince").list();
        List<Object[]>lists=session.createQuery("select id,name,code from TAddressProvince").list();
        for (int i=0;i<lists.size();i++){
            Object[]obj=lists.get(i);
            System.out.println(obj[0]+"  :  "+obj[1]+"  :  "+obj[2]);
        }

        List<TAddressProvince>plists=session.createQuery("select new TAddressProvince( id,name,code) from TAddressProvince").list();
        for (int i=0;i<plists.size();i++){

            System.out.println(plists.get(i).getId()+"  :  "+plists.get(i).getName()+"  :  "+plists.get(i).getCode());
        }
        HibernateUtil.closeSession(session);
    }
}

​

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值