• 008多对一 关联映射 --- many-to-one


    • 多对一 --- many-to-one
    • 一对多 --- one-to-many
    • 一对一 --- one-to-one
    • 多对多 --- many-to-many

    场景:用户和组;从用户角度来,多个用户属于一个组(多对一 关联)

    使用hibernate开发的思路:先建立对象模型(领域模型),把实体抽取出来。

    目前两个实体:用户和组两个实体,多个用户属于一个组,那么一个用户都会对应于一个组,所以用户实体中应该有一个持有组的引用。

    关联映射的本质:

     将关联关系映射到数据库,所谓的关联关系是对象模型在内存中一个或多个引用。

    User实体类:

    public class User {
    
        private int id;
    
        private String name;
    
        private Group group;
    
     
    
        public Group getGroup() {
    
            return group;
    
        }
    
    public void setGroup(Group group) {
    
            this.group = group;
    
        }
    
        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;
    
        }
    
    }

    Group实体类:

    public class Group {
    
        private int id;
    
        private String name;
    
        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;
    
        }
    
    }

    实体类建立完后,开始创建映射文件,先建立简单的映射文件:

    Group实体类的映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.Group" table="t_group">
    
            <id name="id" column="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="name"/>
    
        </class>
    
    </hibernate-mapping>

    User实体类的映射文件:

    <hibernate-mapping>
    
        <class name="com.wjt276.hibernate.User" table="t_user">
    
            <id name="id" column="id">
    
                <generator class="native"/>
    
            </id>
    
            <property name="name"/>
    
            <!--<many-to-one> 关联映射 多对一的关系
    
                name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group,
    
                但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid").
    
            这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一
    
                端加入一个外键指向一的一端。
    
             -->
    
            <many-to-one name="group" column="groupid"/>
    
        </class>
    
    </hibernate-mapping>

    ※<many-to-one>标签※:

    例如:<many-to-one name="group" column="groupid"/>

    <many-to-one> 关联映射多对一的关系

    name:是维护的属性(User.group),这样表示在多的一端表里加入一个字段名称为group,但group与SQL中的关键字重复,所以需要重新命名字段(column="groupid").这样这个字段(groupid)会作为外键参照数据库中group表(t_group也叫一的一端),也就是就在多的一端加入一个外键指向一的一端。

             这样导出至数据库会生成下列语句:

    alter table t_user drop foreign key FKCB63CCB695B3B5AC

    drop table if exists t_group

    drop table if exists t_user

    create table t_group (id integer not null auto_increment, name varchar(255), primary key (id))

    create table t_user (id integer not null auto_increment, name varchar(255), groupid integer, primary key (id))

    alter table t_user add index FKCB63CCB695B3B5AC (groupid), add constraint FKCB63CCB695B3B5AC foreign key (groupid) references t_group (id)

    多对一 存储(先存储group(对象持久化状态后,再保存user)):

    session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
       
    
                Group group = new Group();
    
                group.setName("wjt276");
    
                session.save(group); //存储Group对象。
    
               
    
                User user1 = new User();
    
                user1.setName("菜10");
    
                user1.setGroup(group);//设置用户所属的组
    
               
    
                User user2 = new User();
    
                user2.setName("容祖儿");
    
                user2.setGroup(group);//设置用户所属的组
    
               
    
                //开始存储
    
                session.save(user1);//存储用户
    
                session.save(user2);
    
                           
    
                tx.commit();//提交事务

    执行后hibernate执行以下SQL语句:

    Hibernate: insert into t_group (name) values (?)

    Hibernate: insert into t_user (name, groupid) values (?, ?)

    Hibernate: insert into t_user (name, groupid) values (?, ?)

    注意:如果上面的session.save(group)不执行,则存储不存储不成功。则抛出TransientObjectException异常。

    因为Group为Transient状,Object的id没有分配值。

     

    结果:persistent状态的对象是不能引用Transient状态的对象

    以上代码操作,必须首先保存group对象,再保存user对象。我们可以利用cascade(级联)方式,不需要先保存group对象。而是直接保存user对象,这样就可以在存储user之前先把group存储了。

        利用cascade属性是解决TransientObjectException异常的一种手段。

    重要属性-cascade(级联):

        级联的意思是指定两个对象之间的操作联运关系,对一个 对象执行了操作之后,对其指定的级联对象也需要执行相同的操作,取值:all、none、save_update、delete

     

    1、  all:代码在所有的情况下都执行级联操作

    2、  none:在所有情况下都不执行级联操作

    3、  save-update:在保存和更新的时候执行级联操作

    4、  delete:在删除的时候执行级联操作。

    例如:<many-to-one name="group" column="groupid" cascade="save-update"/>

    多对一  加载数据

    代码如下:

    session = HibernateUtils.getSession();
    
                tx = session.beginTransaction();
    
                User user = (User)session.load(User.class, 3);
    
                System.out.println("user.name=" + user.getName());
    
                System.out.println("user.group.name=" + user.getGroup().getName());
          
                //提交事务
    
                tx.commit();

    执行后向SQL发出以下语句:

    Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.groupid as groupid0_0_ from t_user user0_ where user0_.id=?

    Hibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=?

    可以加载Group信息:因为采用了<many-to-one>这个标签,这个标签会在多的一端(User)加一个外键,指向一的一端(Group),也就是它维护了从多到一的这种关系,多指向一的关系。当你加载多一端的数据时,它就能把一的这一端数据加载上来。当加载User对象后hibernate会根据User对象中的groupid再来加载Group信息给User对象中的group属性

     

     

  • 相关阅读:
    phalcon——HTTP 请求
    phalcon——闪存消息
    phalcon——验证
    Java 字符串分隔 split
    Eclipse "R cannot be resolved"问题
    Android CountDownTimer 类实现倒计时
    Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素
    Android Studio 设置/更改 SDK 路径
    Android 开发使用自定义字体
    Android Studio "ADB not responding"
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4076728.html
Copyright © 2020-2023  润新知