【springmvc+mybatis项目实战】杰信商贸-19.级联删除

我们从写项目开始到现在,一共完成了生产厂家、购销合同、货物(购销合同下的)、附件(货物下的)这四大块的大部分业务。

我们的生产厂家、购销合同、货物(购销合同下的)、附件(货物下的)这四大块的关系我们来回顾一下:

我们先不管生产厂家(因为它可以和后三个关联关系最弱)。
购销合同与货物是一对多的关系,而货物与附件又是一对多的关系。那么购销合同与附件是两层一对多的关系。这里我们要注意,在两层一对多结构中,子表数据不设置外键关联时,就称为僵尸数据。

因为我们的购销合同、货物、附件表虽然都存储有关联关系的表的主键的字段,但是并没有设置外键,加入当我们删除购销合同时,我们之前写的删除方法就已经不行了,删除了购销合同后,并没有将购销合同下的所有货物,以及货物的所有附件删除。

所以接下来我们要利用“级联删除”,来解决我们为了图省事而没有设外键引发的问题。
我们来看一下“级联删除”:

Hibernate 多层关联最简单;配置关联关系时,只关系上下级对象。(hibernate的强项)
Mybatis 多层关联关系时,级联删除必须一级一级的删除。多级时要专门写mapper方法。(这就是MyBatis的弱项,官方没有办法解决= =,只能通过你自己的办法解决)

有两种级联映射的方法:

1)在mybatis在service,删除货物时,先调用附件的service删除方法
2)通过sql,高速删除(批量删除)每层都要实现一个删除

我们使用第二种方法解决刚刚我们所说的问题,就要分别在货物和购销合同的Mapper下增加级联删除的SQL配置

首先我们在附件的ContractProductMapper.xml中添加级联删除的代码:

<!-- 级联删除 -->
<delete id="deleteByContractProductById" parameterType="string">
	delete from ext_cproduct_c
	where contract_product_id in
	<foreach collection="array" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</delete>

然后在货物的ContractMapper.xml中添加级联删除的代码:

<pre name="code" class="html"><!-- 级联删除 删除合同时同时删除合同下的货物-->
<delete id="deleteByContractById" parameterType="string">
	delete from contract_product_c
	where contract_id in
	<foreach collection="array" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</delete>

<!-- 级联删除 删除合同时删除合同货物下的所有附件-->
<delete id="deleteExtByContractById" parameterType="string">
	delete from ext_cproduct_c
	where contract_product_id in(
		select contract_product_id from contract_product_c
		where contract_id in
		<foreach collection="array" item="id" open="(" close=")" separator=",">
			#{id}
		</foreach>
	)
</delete>

先来给ContractProduct来加新的级联删除的逻辑:首先是Dao层ContractProductDao.java:

package cn.hpu.jk.dao;

import java.io.Serializable;

import cn.hpu.jk.domain.ContractProduct;

public interface ContractProductDao extends BaseDao<ContractProduct>{
	//我们这里可以直接使用继承的BaseDao的增删改查方法
	//创建一系列其它Dao的原因是因为其它Dao有可能需要拓展

	//拓展的级联删除方法
	public void deleteByContractProductById(Serializable[] ids) throws Exception;
}

ContractProductDaoImpl.java:

package cn.hpu.jk.dao.impl;

import java.io.Serializable;

import org.springframework.stereotype.Repository;

import cn.hpu.jk.dao.ContractProductDao;
import cn.hpu.jk.domain.ContractProduct;

@Repository //为了包扫描的时候这个Dao被扫描到
public class ContractProductDaoImpl extends BaseDaoImpl<ContractProduct> implements ContractProductDao{

	public ContractProductDaoImpl(){
		//设置命名空间
		super.setNs("cn.hpu.jk.mapper.ContractProductMapper");
	}

	@Override
	public void deleteByContractProductById(Serializable[] ids) throws Exception {
		super.getSqlSession().delete(super.getNs()+".deleteByContractProductById", ids);

	}

}

接下来是Service层,我们这里不用添加新的方法,只需要修改原来的删除方法即可。
在ContractProductServiceImpl中修改下面方法

//删除多个
@Override
public void delete(Serializable[] ids) {
	try {
		//先删除所有货物下的附件
		contractProductDao.deleteByContractProductById(ids);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	contractProductDao.delete(ids);
}

//删除一个
@Override
public void deleteById(Serializable id) {
	Serializable[] ids={id};
	try {
		//先删除所有货物下的附件
		contractProductDao.deleteByContractProductById(ids);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	contractProductDao.deleteById(id);
}

下面重启服务器进行测试:
我们进入购销合同列表,我们测试第一条购销合同的数据,点击它的“货物”

我们可以看到此购销合同下有两条记录,我们点击第一条(厂家为“喜福来”)数据的“附件”

发现第一条货物下有2个附件,分别来自“瑞成电镀厂”和“综艺花纸”。

观察一下数据库,这两条数据也是存在的。

我们在货物那一层进行删除,我们删除第一条(厂家为“喜福来”)数据。

然后我们回到数据库中,发现来自“瑞成电镀厂”和“综艺花纸”的附件已经被删除了:

所以我们货物和附件的级联删除完成。

同理我们在购销合同下也是这么做
首先是Dao层
ContractDao.java:

package cn.hpu.jk.dao;

import java.io.Serializable;
import java.util.Map;

import cn.hpu.jk.domain.Contract;

public interface ContractDao extends BaseDao<Contract>{
	//我们这里可以直接使用继承的BaseDao的增删改查方法
	//创建一系列其它Dao的原因是因为其它Dao有可能需要拓展

	public void updateState(Map map);//修改状态

	//拓展的级联删除方法
	public void deleteByContractById(Serializable[] ids) throws Exception;
	public void deleteExtByContractById(Serializable[] ids) throws Exception;
}

ContractDaoImpl.java:

package cn.hpu.jk.dao.impl;

import java.io.Serializable;
import java.util.Map;

import org.springframework.stereotype.Repository;

import cn.hpu.jk.dao.ContractDao;
import cn.hpu.jk.domain.Contract;

@Repository //为了包扫描的时候这个Dao被扫描到
public class ContractDaoImpl extends BaseDaoImpl<Contract> implements ContractDao{

	public ContractDaoImpl(){
		//设置命名空间
		super.setNs("cn.hpu.jk.mapper.ContractMapper");
	}

	@Override
	public void updateState(Map map) {
		super.getSqlSession().update(super.getNs()+".updateState", map);
	}

	@Override
	public void deleteByContractById(Serializable[] ids) throws Exception {
		super.getSqlSession().update(super.getNs()+".deleteByContractById", ids);
	}

	@Override
	public void deleteExtByContractById(Serializable[] ids) throws Exception {
		super.getSqlSession().update(super.getNs()+".deleteExtByContractById", ids);

	}
}

然后是Service层,在ContractServiceImpl中修改下面方法

@Override
public void delete(Serializable[] ids) {

	try {
		//删除合同时删除合同货物下的所有附件
		contractDao.deleteExtByContractById(ids);
	} catch (Exception e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}

	try {
		//删除合同时同时删除合同下的货物
		contractDao.deleteByContractById(ids);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	contractDao.delete(ids);
}

@Override
public void deleteById(Serializable id) {
	Serializable[] ids={id};

	try {
		//删除合同时删除合同货物下的所有附件
		contractDao.deleteExtByContractById(ids);
	} catch (Exception e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}

	try {
		//删除合同时同时删除合同下的货物
		contractDao.deleteByContractById(ids);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	contractDao.deleteById(id);
}

我们进行测试,现在我又添加了一些测试数据,首先我们点击第三条购销合同数据

发现其下有2条货物数据

点击“康达”的货物信息(我只在康达下增加了附件,“平遥远江”下没有附件),下面又有两条附件数据

并且我们的货物以及附件数据在数据库中都存在

接下来,我们删除第三条购销合同数据

然后去数据库中查看,发现合同下的货物,合同下货物的附件信息已经全部删除完毕

至此,我们的级联删除功能完成!

思考:我们每次删除完都要去下一级或者数据库看看我们删除了没有,可不可以直接在合同列表中显示每个合同下的货物有多少件?可不可以在货物列表下显示每个货物下有多少个附件?答案当然是可以,我们下一篇总结再详谈。

转载请注明出处:http://blog.csdn.net/acmman/article/details/48595867

时间: 2024-11-03 16:37:24

【springmvc+mybatis项目实战】杰信商贸-19.级联删除的相关文章

【springmvc+mybatis项目实战】杰信商贸-1.项目背景

1.项目背景 杰信项目物流行业的项目, 杰信商贸是国际物流行业一家专门从事进出口玻璃器皿贸易的公司.公司总部位于十一个朝代的帝王之都西安,业务遍及欧美.随着公司不断发展壮大,旧的信息系统已无法满足公司的快速发展需求,妨碍公司成长,在此背景下,公司领导决定研发<杰信商贸综合管理平台>. <杰信商贸综合管理平台>分三期完成.一期完成仓储管理(包括:采购单.仓库.货物.条形码.入库.出库.退货.盘点.库存.库存上限报警.统计查询)和展会管理(包括:展会管理.出单管理),形成货物统一数字化

【springmvc+mybatis项目实战】杰信商贸-13.购销合同列表

我们接下来开始编写购销合同的列表业务 首先我们现往我们的FACTORY_C和基础表中倒入一些数据方便我们测试 导入数据的SQL文件:jk.sql (点击下载) 然后我们看到数据已经插入 启动服务器查看我们的数据已经插入 接下来我们开始做购销合同的业务.首先我们的数据库表已经建立(CONTRACT_C),我们首先创建购销合同的实体类Contract.java: package cn.hpu.jk.domain; import java.util.Date; public class Contrac

【springmvc+mybatis项目实战】杰信商贸-31.出口报运业务-购销合同查询与上报

我们上一篇完成了出口报运增删查修的mapper+Dao+Service+Controller,而且在Controller中添加和获取出口报运的列表的方法,然后成功获取了出口报运的列表: 然后我们这次要添加出口报运的"新增"方法,但是这个"新增"和以往的新增方法不同,这个要与之前的购销合同关联在一起. 我们出口报运的"新增"是这样的: 用户要选择多个合同,然后进行报运.(体现出业务关联) 报运新增时,报运专责只能看到已上报的购销合同. (操作出口报

【springmvc+mybatis项目实战】杰信商贸-11.购销合同业务

生产厂家我们做完了,接下来我们要做一个更加复杂的业务,就是"货运管理" 首先我们先了解一下业务,什么是"货运管理"? "货运管理"是国际物流的概念,往常我们货物送到国内没有那么多事情,但是货物发往国外就多了很多手续,依靠小物流公司我们是很不可能的,需要行业的大背景的支撑.下面我们来看看它是怎么做的 a)业务:购销合同 当我们的客户通过展会.其它渠道跟杰信公司联系上以后,他们看上杰信的货物样品,他们会跟杰信签订一个购买合同(样式要求,货物数量),客

【springmvc+mybatis项目实战】杰信商贸-15.细粒度的权限控制+业务上报取消

上一篇总结我们完成了购销合同的增删改查业务,这一篇我们首先完成权限控制以及业务的上报取消的设置功能. 先说我们的权限控制 1.细粒度的权限控制 a)日常权限框架: 基于角色权限,用户.角色.权限(URL.主菜单.左侧菜单.按钮) b)数据权限: 纵向的数据权限过滤:对数据进行过滤 1)本人(专责):登录后只能看到自己的信息Where条件 create_by = #{当前登录者id} 2)部门(集团公司):登录后登录人是经理级别A.只能看本部门Where条件 create_dept=#{当前登录者

【springmvc+mybatis项目实战】杰信商贸-20.合同货物数和附件数

我们上一篇完成了购销合同.货物以及附件的级联删除,这次我们需要做的业务就是----要求直接显示合同下的货物数和附件数 上一次我们遗留的问题: 我们每次删除完都要去下一级或者数据库看看我们删除了没有,我们可以直接在合同列表中显示每个合同下的货物以及货物的附件有多少件,这样就避免了反复去下一级查看列表的繁琐操作. 那么下面我们使用SQL来编写获取合同下的货物数: select count(*) from contract_product_c where contract_id='928eb2ae-2

【springmvc+mybatis项目实战】杰信商贸-4.maven依赖+PO对+映射文件

我们来为刚刚创建的数据库表来在工程中创建PO对象 首先我们要创建工程 项目的开发环境 序号 工  具                用  途 1 MyEclipse 2014   IDE 2 JDK 1.7.9        Java虚拟机 3 TOMCAT 7.0.26       中间件 4 Oracle11g/10g.MySQL 5.0.87数据库 5 PL/SQL .SQLyog 8.2SQL控制台 6 apache-maven-3.0.5MAVEN 7 PowerDesigner 15

【springmvc+mybatis项目实战】杰信商贸-8.生产厂家修改

上一次我们做了生产厂家的新增,下面我们来做一下生产厂家的修改 回顾一下我们的FactoryMapper.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

【springmvc+mybatis项目实战】杰信商贸-23.重点知识回顾

1.重点知识回顾 购销合同查看,采用类似hibernate方式,都以对象关联方式. (1)PO为了利用MyBatis性能,在创建时,没有采用关联对象关联,而是将对象关键字段,也就是外键,利用这个普通属性,来记录值,表数据间关联关系存在,但对象关联关系不存在.代码也就变得简单.在货物新增时,只要从主对象中携带过来,主表ID即可. (2)VO为了方便对象关联时取数据.在列表循环货物信息时,要去查询当前货物下的附件时,如果采用上面的方式,只能再次查询.但是我们以对象关联方式,可以直接获取到当前货物下的