zoukankan      html  css  js  c++  java
  • Hibernate一对一

    1.使用共享主键方式

    <class name="com.tazi.domin.User" table="USERS">
    	<id name="id"  type="java.lang.Integer">
    		<column name="ID"/>
    		<generator class="identity"/>
    	</id>
    	<property name="username" type="string" column="USERNAME"/>	
    	<property name="password" type="string" column="PASSWORD"/>		
    	<one-to-one name="profile" class="com.tazi.domin.Profile"cascade="none />
    </class> 
       <class name="com.tazi.domin.Profile" table="profile" catalog="hib" >
            <id name="id" type="java.lang.Integer">
                <column name="ID" />
                <generator class="foreign" >
                	<param name="property">user</param>
                </generator>
            </id>
             
            <property name="birth" type="java.sql.Timestamp" column="BIRTHDATE"/>
            <property name="age" type="java.lang.Integer" column="AGE"/>
            <one-to-one name="user" class="com.tazi.domin.User" />
        </class>
    

    测试:

    (1). 

    profile.setUser(user);//profile的主键依赖于user的主键
    user.setProfile(profile);

    session.save(user);//user中one-to-one 设置cascade=none

    则实际只保存了user,这是显然的。

    (2).session.save(user); //user中one-to-one设置cascade=all

    则保存user后保存profile

    Hibernate: 
        insert 
        into
            USERS
            (USERNAME, PASSWORD) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            hib.profile
            (BIRTHDATE, AGE, ID) 
        values
            (?, ?, ?)
    

    (3). session.save(profile); //profile 的one-to-one中没有进行任何cascade设置,甚至cascade="none"执行结果与(2)相同。因为profile的主键是由表user产生的。

    (4).User user=(User)session.get(User.class, 2);发现Hibernate使用两次左外连接,显然有些多余。当session.get(Profile.class,2)时结果也是两次外连接。

    Hibernate: 
        select
            user0_.ID as ID1_2_,
            user0_.USERNAME as USERNAME1_2_,
            user0_.PASSWORD as PASSWORD1_2_,
            profile1_.ID as ID2_0_,
            profile1_.BIRTHDATE as BIRTHDATE2_0_,
            profile1_.AGE as AGE2_0_,
            user2_.ID as ID1_1_,
            user2_.USERNAME as USERNAME1_1_,
            user2_.PASSWORD as PASSWORD1_1_ 
        from
            USERS user0_ 
        left outer join
            hib.profile profile1_ 
                on user0_.ID=profile1_.ID 
        left outer join
            USERS user2_ 
                on profile1_.ID=user2_.ID 
        where
            user0_.ID=?
    

    (5).如果此时在Profile的one-to-one中设置fetch="select",则结果如下:

    Hibernate: 
        select
            user0_.ID as ID1_1_,
            user0_.USERNAME as USERNAME1_1_,
            user0_.PASSWORD as PASSWORD1_1_,
            profile1_.ID as ID2_0_,
            profile1_.BIRTHDATE as BIRTHDATE2_0_,
            profile1_.AGE as AGE2_0_ 
        from
            USERS user0_ 
        left outer join
            hib.profile profile1_ 
                on user0_.ID=profile1_.ID 
        where
            user0_.ID=?
    

    可见,在一对一关联中,Hibernate默认使用左外连接的方式进行查询。

    (6).在Profile中 增加constrained="true"

     <one-to-one name="user" class="com.tazi.domin.User" constrained="true"/>

    则User user=(User)session.get(User.class, 2);执行结果如下:

    Hibernate: 
        select
            user0_.ID as ID1_1_,
            user0_.USERNAME as USERNAME1_1_,
            user0_.PASSWORD as PASSWORD1_1_,
            profile1_.ID as ID2_0_,
            profile1_.BIRTHDATE as BIRTHDATE2_0_,
            profile1_.AGE as AGE2_0_ 
        from
            USERS user0_ 
        left outer join
            hib.profile profile1_ 
                on user0_.ID=profile1_.ID 
        where
            user0_.ID=?
    

     其实 增加constrained="true",单独获取Profile(session.get(Profile.class,3)),会发现并没有立刻加载User

    Hibernate: 
        select
            profile0_.ID as ID2_0_,
            profile0_.BIRTHDATE as BIRTHDATE2_0_,
            profile0_.AGE as AGE2_0_ 
        from
            hib.profile profile0_ 
        where
            profile0_.ID=?
    

    (7).delete操作时,会先删除不被其他表引用的表记录

    User user=(User)session.get(User.class, 4);
    session.delete(user); 
    Hibernate: 
        delete 
        from
            hib.profile 
        where
            ID=?
    Hibernate: 
        delete 
        from
            USERS 
        where
            ID=?
    

     2.唯一外键方式

    <class name="com.tazi.domin.User" table="USERS">
    		<id name="id"  type="java.lang.Integer">
    			<column name="ID"/>
    			<generator class="identity"/>
    		</id>
    		<property name="username" type="string" column="USERNAME"/>	
    		<property name="password" type="string" column="PASSWORD"/>	
    		
    		<one-to-one name="profile" class="com.tazi.domin.Profile"
    		cascade="all" property-ref="user"
    		 />
    </class>
    
        <class name="com.tazi.domin.Profile" table="profile" catalog="hib" >
            <id name="id" type="java.lang.Integer">
                <column name="ID" />
                <generator class="identity" />            	   
            </id>
            <property name="birth" type="java.sql.Timestamp" column="BIRTHDATE"/>
            <property name="age" type="java.lang.Integer" column="AGE"/>
            <many-to-one name="user" class="com.tazi.domin.User" unique="true" >
            	<column name="USERID"/>
            </many-to-one>
        </class>
    

     (1).session.save(user)的执行结果如下:

    Hibernate: 
        insert 
        into
            USERS
            (USERNAME, PASSWORD) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            hib.profile
            (BIRTHDATE, AGE, USERID) 
        values
            (?, ?, ?)
    

    (2).session.get(User.class,14)的结果:

    Hibernate: 
        select
            user0_.ID as ID1_1_,
            user0_.USERNAME as USERNAME1_1_,
            user0_.PASSWORD as PASSWORD1_1_,
            profile1_.ID as ID2_0_,
            profile1_.BIRTHDATE as BIRTHDATE2_0_,
            profile1_.AGE as AGE2_0_,
            profile1_.USERID as USERID2_0_ 
        from
            USERS user0_ 
        left outer join
            hib.profile profile1_ 
                on user0_.ID=profile1_.USERID 
        where
            user0_.ID=?
    

    它根据外键取出关联表(profile)的数据

    (3)如果在主方(User)的one-to-one配置中去掉property-ref="user",

    session.get(User.class,14)的结果如下:

        select
            user0_.ID as ID1_1_,
            user0_.USERNAME as USERNAME1_1_,
            user0_.PASSWORD as PASSWORD1_1_,
            profile1_.ID as ID2_0_,
            profile1_.BIRTHDATE as BIRTHDATE2_0_,
            profile1_.AGE as AGE2_0_,
            profile1_.USERID as USERID2_0_ 
        from
            USERS user0_ 
        left outer join
            hib.profile profile1_ 
                on user0_.ID=profile1_.ID 
        where
            user0_.ID=?
    

      它根据主键相等作为连接条件,显然是错误的。所以必须加上property-ref="user",它指示User在加载关联的Profile时连接条件是通过哪一个属性(默认是id所对应的属性)

     (4).session.delete(user)的执行结果与上面1中的delete执行结果相同,都是根据id删除的,而不是根据外键,虽然外键也是唯一的。因为在delete之前,必须先得到数据库中记录对应的持久化对象,取得后id属性一定是已知的。如果在主方(独立方)没有设置cascade="all",则session.delete(user)不会成功,这是由于数据库中外键约束引起的。

  • 相关阅读:
    ArrayList用法
    MessageBox
    将文本文件导入Sql数据库
    在桌面和菜单中添加快捷方式
    泡沫排序
    Making use of localized variables in javascript.
    Remove double empty lines in Visual Studio 2012
    Using Operations Manager Connectors
    Clear SharePoint Designer cache
    Programmatically set navigation settings in SharePoint 2013
  • 原文地址:https://www.cnblogs.com/tazi/p/2285190.html
Copyright © 2011-2022 走看看