Hibernate的多对一的关系查询

Hibernate的多对一的关系查询

配置步骤

1.创建一个可以存储多个表数据的实体类,多对一的关系

//联系人和客户是多对一的关系,意味着一个联系人对应一个客户
//所以,一个联系人里面只有一个可以存储一个客户数据的属性就可以了。
//所以使用Customer的引用
private Customer customer;

public Customer getCustomer() {
    return customer;
}
public void setCustomer(Customer customer) {
    this.customer = customer;
}

2.将查询的多个表的数据封装这个实体累的对象里面,通过配置来说实现。

<many-to-one name="customer" column="lkm_cust_id"></many-to-one>

注意:,但是这样的方式会引起字段冲突,两个外键字段名都相同,程序不知道要对哪一个进行操作

代码

持久化类

Customer

public class Customer {
    private Long custId;//bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
    private String custName;//varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
    private String custSource;//varchar(32) DEFAULT NULL COMMENT '客户信息来源',
    private String custIndustry;//varchar(32) DEFAULT NULL COMMENT '客户所属行业',
    private String custLevel;//varchar(32) DEFAULT NULL COMMENT '客户级别',
    get()/set()......
}

Linkman

public class Linkman {
    private Long lkmId;//主键
    private String lkmName;
    private Long lkmCustId;//外键
    private String lkmGender;
    private String lkmPhone;
    private String lkmMobile;
    private String lkmEmail;
    private String lkmQq;
    private String lkmPosition;
    private String lkmMemo;

    private Customer customer;

    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    get()/set()......
}

Linkman.hbm.xml

  • many-to-one是声明关联文件

  • name属性:设置对应的实体类的属性名

  • column属性:设置多对一的外键字段
  • insert属性:设置实体类对应的属性在插入的时候忽略
  • update属性:设置实体类对应的属性在更新的时候忽略
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.entity.Linkman" table="cst_linkman">
    <id name="lkmId" column="lkm_id">
        <generator class="identity"></generator>
    </id>
    <property name="lkmName" column="lkm_name"></property>

    <!-- 原因:同一个文件里面,如果出现了两个以上的column,在更新的时候和插入的时候,不知道以哪个字段的值为准 -->
    <!-- 解决方案: 
        1.删除一个外键字段
        2.将一个外键字段设置为,插入和更新的时候忽略它的值 insert="false" 和 update="false" -->
    <!-- <property name="lkmCustId" column="lkm_cust_id" /> --> 

    <property name="lkmGender" column="lkm_gender"></property>
    <property name="lkmPhone" column="lkm_phone"></property>
    <property name="lkmMobile" column="lkm_mobile"></property>
    <property name="lkmEmail" column="lkm_email"></property>
    <property name="lkmQq" column="lkm_qq"></property>
    <property name="lkmPosition" column="lkm_position"></property>
    <property name="lkmMemo" column="lkm_memo"></property>

    <!-- 
        配置多对一的关系 
        many-to-one是声明关联文件
        name属性:设置对应的实体类的属性名
        column属性:设置多对一的外键字段
        insert属性:设置实体类对应的属性在插入的时候忽略
        update属性:设置实体类对应的属性在更新的时候忽略 

     -->
    <many-to-one name="customer" column="lkm_cust_id" insert="false" update="false"></many-to-one>

<!--    <many-to-one name="customer" column="lkm_cust_id" insert="false" update="false"></many-to-one>-->   
</class>
</hibernate-mapping>

推荐使用直接注释外键属性的配置。

<!-- <property name="lkmCustId" column="lkm_cust_id" /> --> 

Customer.hbm.xml没有变化

hibernate.cfg.xml继续加载两个映射文件


注意

Linkman映射文件

  1. 为什么一对多和多对一,配置的的都是外键,不用配置主键。

    • 答:原因,因为主键本身就有一个单独的标签标签唯一了。而外键没有单独的标签的。

注意:
1. 必须知道为什么导致字段冲突。
- 因为出现两个属性对应一个数据库的字段column。那么就导致在插入或者更新的时候,程序不知道以哪个属性的值作为正确的数据插入或者更新到数据库。

  1. 必须知道如何解决字段冲突的问题

    • 方式1:直接删除外键属性的配置

      • 缺陷:必须在插入的时候,创建一个对象来设置外键值。
    • 方式2:保留一个单独的属性用于插入和更新使用的外键,将设置了外键的字段(customer)设置为insert=”false” update=”false”,意思就是查询和更新时,忽略该属性的值。

      • 缺陷:级联插入或级联更新会导致外键字段没有值,所以不能使用级联插入或者级联更新
    • 如果要保证功能的完整性,需要支持级联增加,使用多对的关系作为外键属性。直接删除外键属性 (推荐使用)

    • 如果不需要级联增加,那么就可以使用一个属性单独作为外键

直接删除外键属性的配置
  • 如果需要插入数据,就必须创建一个对象来设置外键值
@Test
public void insert(){
    //获得操作对象
    Session session = HibernateUtils.getSession();
    //开启事务
    Transaction transaction = session.beginTransaction();

    //封装数据
    Linkman linkman = new Linkman();
    linkman.setLkmName("马云");

    //创建一个客户表的实体类对象来设置外键值,而且外键值是必须存在的
    Customer customer = new Customer();
    customer.setCustId(3L);
    linkman.setCustomer(customer);

    //保存数据
    session.save(linkman);
    //提交事务
    transaction.commit();
    session.close();
}
查询和更新时,忽略该属性的值。

如果选择保留一个单独的属性用于插入和更新使用的外键,将设置了外键的字段(customer)设置为insert=”false” update=”false”,查询和更新时,忽略该属性的值

  • 那么他的缺陷是级联插入或级联更新会导致外键字段没有值,丢失了值

如果修改后再次使用上面的方法会报错,所以直接给外键值赋值就可以了

@Test
public void insert2(){
    //获得操作对象
    Session session = HibernateUtils.getSession();
    //开启事务
    Transaction transaction = session.beginTransaction();

    //封装数据
    Linkman linkman = new Linkman();
    linkman.setLkmName("马云");

    //直接给外键赋值
    linkman.setLkmCustId(3L);

    //保存数据
    session.save(linkman);
    //提交事务
    transaction.commit();
    session.close();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值