• hibernate 多对多关系总结


        hibernate中,对对象关系的映射处理估计是最让人迷惑和头疼的,特别是cascade和inverse属性的使用,不知已经杀死了我多少个脑细胞了,好记性永远比不上烂笔头,为了能节省自己的脑细胞,降低猝死的出现概率,暂且在此记录一下自己的学习内容,以便日后查阅:

    实体对象关系说明:

        1、用户类(user)->tb_pms_user

        2、用户组(group)->tb_pms_group

       其中,一个用户组可以包含多个用户,一个用户可以加入多个用户组,多对多关系。

    Spring的配置文件:

      1 <?xml version="1.0" encoding="UTF-8"?>  
      2     <beans xmlns="http://www.springframework.org/schema/beans"  
      3            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      4            xmlns:aop="http://www.springframework.org/schema/aop"  
      5           xmlns:tx="http://www.springframework.org/schema/tx"  
      6            xmlns:jee="http://www.springframework.org/schema/jee"  
      7            xsi:schemaLocation="  
      8            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
      9           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd  
     10           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
     11           http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">  
     12           
     13           <bean id="propertyConfigurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     14            <property name="locations">  
     15             <list>    
     16                <value>/WEB-INF/deploy/pms/app-config/jdbc.properties</value>   
     17              </list> 
     18               </property> 
     19             </bean>
     20           
     21           
     22           <!-- 配置数据原 -->
     23             <bean id="dataSource"
     24                class="org.apache.commons.dbcp.BasicDataSource">
     25             <property name="driverClassName"
     26                 value="com.mysql.jdbc.Driver">
     27             </property>
     28             <property name="url" value="jdbc:mysql://localhost:3306/pms"></property>
     29             <property name="username" value="root"></property>
     30             <property name="password" value="1qaz!QAZ"></property>
     31            </bean>
     32        
     33        <!-- 配置session工厂 -->
     34        <bean id="sessionFactory"
     35           class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     36             <property name="dataSource">
     37             <ref bean="dataSource" />
     38              </property>
     39            <property name="mappingResources">
     40             <list>
     41               <value>com/pms/entity/TbPmsGroup.hbm.xml</value> 
     42               <value>com/pms/entity/TbPmsUser.hbm.xml</value>             
     43             </list>
     44          </property>
     45          <property name="hibernateProperties">
     46             <props>
     47                <prop key="hibernate.dialect">
     48                      org.hibernate.dialect.MySQLDialect
     49                </prop>
     50                <prop key="hibernate.show_sql">true</prop>
     51             </props>
     52          </property>
     53         </bean>
     54      <!-- spring jdbcTemplate -->     
     55     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">    
     56         <property name="dataSource" ref="dataSource"></property>    
     57     </bean>
     58     
     59     <!-- 事务管理器 -->
     60     <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
     61       <property name="sessionFactory">
     62            <ref local="sessionFactory" />
     63       </property>
     64     </bean>
     65     <!-- 事务代理拦截器的配置 -->
     66     <bean id="baseTransactionProxy" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
     67       <property name="transactionManager">
     68            <ref bean="transactionManager" />
     69       </property>
     70     <property name="transactionAttributes">
     71     <props>
     72     <prop key="insert*">PROPAGATION_REQUIRED</prop>
     73     <prop key="update*">PROPAGATION_REQUIRED</prop>
     74     <prop key="delete*">PROPAGATION_REQUIRED</prop>
     75     <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
     76     </props>
     77     </property>
     78     </bean>
     79     
     80     <!-- 日志bean 
     81     <bean id="logSupport" class="com.shproject.log.impl.LogSupportImpl"/>
     82     
     83     
     84     <aop:config>
     85       <aop:aspect id="addLog" ref="logSupport">
     86         <aop:pointcut id="servicePointCut" expression="execution(* com.shproject.service.impl.*.* (..))"/>
     87         <aop:after method="addLog" pointcut-ref="servicePointCut"/>
     88       </aop:aspect>
     89     </aop:config>
     90     -->
     91     <bean id="baseDao" class="com.pms.base.BaseDao">
     92        <property name="sessionFactory">
     93          <ref bean="sessionFactory"/>
     94       </property>
     95       <property name="jdbcTemplate">
     96          <ref bean="jdbcTemplate"/>
     97       </property>
     98     </bean>
     99     
    100     
    101     
    102     <bean id="userDao" class="com.pms.dao.impl.TbPmsUserDaoImpl" parent="baseDao">        
    103     </bean>
    104     
    105     <bean id="groupDao" class="com.pms.dao.impl.TbPmsGroupDaoImpl" parent="baseDao">        
    106     </bean>
    107     
    108     
    109     <bean id="userService" class="com.pms.service.impl.UserServiceImpl">
    110       <property name="userDao">
    111          <ref bean="userDao"/>
    112       </property>
    113     </bean>
    114     
    115     <bean id="groupService" class="com.pms.service.impl.GroupServiceImpl">
    116       <property name="groupDao">
    117          <ref bean="groupDao"/>
    118       </property>
    119     </bean>
    120          
    121 </beans>  
    View Code

    实体类及映射文件:

    TbPmsUser.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2013-7-22 10:23:27 by Hibernate Tools 3.2.4.GA -->
     5 <hibernate-mapping>
     6     <class name="com.pms.entity.TbPmsUser" table="tb_pms_user">
     7            <id name="userid" type="string" column="F_USERID">
     8                  <generator class="uuid.hex" /> 
     9            </id>
    10             <property name="name" type="string" column="F_NAME">
    11             
    12             </property>
    13             <property name="email" type="string" column="F_EMAIL">
    14           
    15             </property>
    16             <property name="mobile" type="string" column="F_MOBILE">
    17              
    18             </property>
    19             <property name="password" type="string" column="F_PASSWORD">
    20                 
    21             </property>
    22             <property name="flag" type="java.lang.Integer" column="F_FLAG">
    23              
    24             </property>
    25             <property name="registertime" type="date" column="F_REGISTERTIME">
    26                 
    27             </property>
    28             <property name="lastlogin" type="date" column="F_LASTLOGIN">
    29                 
    30             </property>
    31             <property name="areaid" type="string" column="F_AREAID">
    32                 
    33             </property>
    34             <property name="levelId" type="java.lang.Integer" column="F_LEVEL_ID">
    35                
    36             </property>
    37             <property name="hostid" type="string" column="F_HOSTID">
    38                
    39             </property>
    40             <property name="islock" type="java.lang.Integer" column="F_ISLOCK">
    41                 
    42             </property>
    43             <property name="lockdatebegin" type="date" column="F_LOCKDATEBEGIN">
    44               
    45             </property>
    46             <property name="ifSuperuser" type="string" column="IF_SUPERUSER">
    47                
    48             </property>
    49             <property name="lastmodify" type="date" column="F_LASTMODIFY">
    50                
    51             </property>
    52             
    53             <set name="groups" table="tb_pms_user_group" cascade="none" inverse="false">
    54                 <key column="F_USERID"/>
    55                 <many-to-many column="F_GROUPID" class="com.pms.entity.TbPmsGroup"/>               
    56             </set>
    57     </class>
    58 </hibernate-mapping>
    View Code

    TbPmsGroup.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2013-7-22 10:23:27 by Hibernate Tools 3.2.4.GA -->
     5 <hibernate-mapping>
     6     <class name="com.pms.entity.TbPmsGroup" table="tb_pms_group">      
     7             <id name="groupid" type="string" column="F_GROUPID">             
     8                 <generator class="uuid.hex" /> 
     9             </id>
    10             <property name="groupname" type="string" column="F_GROUPNAME">
    11             </property>
    12             <property name="flag" type="java.lang.Integer" column="F_FLAG">
    13             </property>
    14             <property name="areaId" type="string" column="F_AREA_ID">
    15             </property>
    16             <property name="groupdesc" type="string" column="F_GROUPDESC">              
    17             </property>
    18             
    19             <set name="users" table="tb_pms_user_group" lazy="true" inverse="false" cascade="none">
    20                 <key column="F_GROUPID"/>
    21                 <many-to-many column="F_USERID" class="com.pms.entity.TbPmsUser"/>
    22             </set>
    23 
    24     </class>
    25 </hibernate-mapping>
    View Code

    关于casecad

          cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所有 cascade的关系就会被自己动的插入或是删除。便是为了能正确的cascade,unsaved-value是个很重要的属性。Hibernate通 过这个属性来判断一个对象应该save还是update,如果这个对象的id是unsaved-value的话,那说明这个对象不是 persistence object要save(insert);如果id是非unsaved-value的话,那说明这个对象是persistence object(数据库中已存在),只要update就行了。saveOrUpdate方法用的也是这个机制。

    关于inverse

           inverse属性主要是用来说明两个模型间的关系究竟该怎么维护的,为true时说明两者的关系由对方去维护,为false时说明关系由自己维护,默认是false的,就是说关系的两端都来维护关系。这个意思就是说,如有一个Student,Teacher和TeacherStudent表,Student和Teacher是多对多对多关系,这个关系由TeacherStudent这个表来表现。那么什么时候插入或删除TeacherStudent表中的记录来维护关系呢?在用hibernate时,我们不会显示的对TeacherStudent表做操作。对TeacherStudent的操作是hibernate帮我们做的。hibernate就是看hbm文件中指定的是"谁"维护关系,那个在插入或删除"谁"时,就会处发对关系表的操作。前提是"谁"这个对象已经知道这个关系了,就是说关系另一头的对象已经set或是add到"谁"这个对象里来了。前面说过inverse默认是false,就是关系的两端都维护关系,对其中任一个操作都会处发对表系表的操作。当在关系的一头,如Student中的bag或set中用了inverse="true"时,那就代表关系是由另一关维护的(Teacher)。就是说当这插入Student时,不会操作TeacherStudent表,即使Student已经知道了关系。只有当Teacher插入或删除时才会处发对关系表的操作。所以,当关系的两头都用inverse="true"是不对的,就会导致任何操作都不处发对关系表的操作。当两端都是inverse="false"或是default值是,在代码对关系显示的维护也是不对的,会导致在关系表中插入两次关系。 

    在一对多关系中inverse就更有意义了。在多对多中,在哪端inverse="true"效果差不多(在效率上)。但是在一对多中,如果要一方维护关 系,就会使在插入或是删除"一"方时去update"多"方的每一个与这个"一"的对象有关系的对象。而如果让"多"方面维护关系时就不会有update 操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。当然这时也要遍历"多"方的每一个对象显示的操作修关系的变化体现到DB中。不管 怎样说,还是让"多"方维护关系更直观一些。

    (1)对one-to-many而言,改变set,会让hibernate执行一系列的update语句, 不会delete/insert数据

    (2)对many-to-many而言,改变set,只修改关系表的数据,不会影响many-to-many的另一方。

    (3)虽然one-to-many和many-to-many的数据库操作不一样,但目的都是一个:维护数据的一致性。

     

     

    另记:在进行Delete和updete操作时,要先把对象get出来使其从脱管态转到持久态,这样才能对其进行操作。

  • 相关阅读:
    Oracle 多版本控制
    texedo 分布式事务
    OLAP 大表和小表并行hash join
    分页SQL模板
    全表扫描分页
    索引的结构图
    利用函数索引优化<>
    分页SQL取下一页
    SORT ORDER BY STOPKEY
    压缩跟踪(CT)代码具体学习_模块1(样本的採集和扩充)
  • 原文地址:https://www.cnblogs.com/angryprogrammer/p/3217592.html
Copyright © 2020-2023  润新知