zoukankan      html  css  js  c++  java
  • 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属性

     

     

  • 相关阅读:
    Windows Store App 主题动画
    Windows Store App 过渡动画
    Windows Store App 控件动画
    Windows Store App 近期访问列表
    Windows Store App 文件选取器
    Windows Store App 访问应用内部文件
    Windows Store App 用户库文件分组
    Windows Store App 获取文件及文件夹列表
    Windows Store App 用户库文件夹操作
    Windows Store App 用户库文件操作
  • 原文地址:https://www.cnblogs.com/crazylqy/p/4076728.html
Copyright © 2011-2022 走看看