级联删除

相信学过数据库基础的童鞋们都知道,当有两个表A和B,表A的外键正是表B的主键时,我们会发现,当我们用数据库语言对B表数据进行删除操作的时候,我们会发现根本就删除不了,所以呢,在实际代码中,想要通过点击删除就可以删除?那么就需要对其进行相关操作了,具体的呢,咱就一步一步来,我所写的是通过spring3+hibernate4+struts2+maven写的代码,里面有两个表department 和user,其department的主键did在user中作为外键,这时候就必然会在department.hbm.xml中配置多对多的关系,如下代码:

<hibernate-mapping package="com.cct.entity">
	<class name="Department" table="department">
		<id name="did" type="java.lang.Integer">
            <generator class="increment"/>
		</id>
		<property name="dname" type="java.lang.String"/>
		<property name="description" type="java.lang.String"/>	
	<!--用户和部门之间的关系  -->
		<set name="users" inverse="true"  cascade="all">//cascade参数不要掉
		   <key>
		       <column name="did"></column>
		   </key>
		   <many-to-many class="com.cct.entity.User"></many-to-many>	    
		</set>
	</class>
</hibernate-mapping>

 因为是通过spring的管理,所以在spring.xml中sessionfactory和transactionmanage的配置都要记得,具体代码如下:

<!-- session工厂 -->
     <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>
        <property name="mappingResources">
            <list>
                <value>com/cct/entity/Department.hbm.xml</value>
                 <value>com/cct/entity/User.hbm.xml</value>
                  <value>com/cct/entity/Post.hbm.xml</value>
            </list>
        </property>
    </bean>
    <bean name="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">    
        <property name="sessionFactory">
        <ref local="sessionFactory"/></property>
    </bean> 

<tx:advice id="advice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 5配置切入点 --> <aop:config> <!-- 配置切入点 ,这里的切入点应用的类级别 --> <aop:pointcut id="perform" expression="execution( * com.cct.service..*.*(..))"/> <!-- 建立通知和切入点的结合 --> <aop:advisor advice-ref="advice" pointcut-ref="perform"/> </aop:config>

以上代码中,记得后面的对于transactionManager的处理(tx:开头的和aop:开头)一定不能掉了,在这部分进行了开启事务管理,如果掉了的话就会报错:No Session found for current thread,当然,除此之外,在写Dao层的时候,也需要注意的是,如果用的是hibernate3,则可以通过继承HibernateDaoSupport来通过hibernatetemplate来进行增删改查操作,当然也是不需要写transaction的开启和提交类似的语句的,如果是hibernate4的话,就需要在Dao中写下下面代码:

        @Resource
	private SessionFactory sessionFactory ;

 通过spring注解特性,用@Resource对sessionfactory进行注入,这样的话在dao层的每个方法中通过sessionfactory.getCurrentSession.*()就可以直接进行增删改查操作,接下来关键的时候到了,那就是在删除操作中,需要进行判断,通过判断departmentservice传过来的参数DeleMode(这个是提前在单独类中定义一些静态变量)来做删除前的解除关系操作,解除关系之后就可以正常删除:

public void deleteDepartmentByID(Serializable id,String  deletemode) {
        Department departement=this.getDepartmentbyId(id);
        if("del".equals(deletemode))
        {
        sessionFactory.getCurrentSession().delete(departement);
        }
        else if("del_pre_release".equals(deletemode))//删除之前先解除关系
        {
            Set<User> departments=departement.getUsers();
            for(User user:departments)
            {
                user.setDepartment(null);
            }
        }
        else{//级联删除    
        }
        sessionFactory.getCurrentSession().delete(departement);    

    }

这样的操作应该是比较常见的,所以有些问题需要注意一下。

posted @ 2016-04-25 22:00  Asher鑫与  阅读(471)  评论(0编辑  收藏  举报