在MySql设定两张表,其中product表的主键设定成orderTb表的外键,具体如下:

产品表:

create table product(id INT(11) PRIMARY KEY,name VARCHAR(32) );

订单表:

create table orderTb(id INT(11) PRIMARY KEY,productid INT(11), FOREIGN KEY(productid) REFERENCES product(id) );

给产品表插入数据如下:

给订单表插入数据如下:

在MySql-Front工具中写SQL文“DELETE from product where id=1”,由于主外键关联,工具会如下报错:

如果用java程序去删(工程下载:https://files.cnblogs.com/files/xiandedanteng/product191006_2.rar )

删除代码:

package com.hy;

import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

public class DeleteProductTest {
    private static Logger logger = Logger.getLogger(DeleteProductTest.class);

    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();
        Reader reader=Resources.getResourceAsReader("mybatis-config.xml");

        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(reader);
        reader.close();

        SqlSession session=ssf.openSession();
        logger.info("Commit Status="+session.getConnection().getAutoCommit());

        try {
            ProductMapper pm=session.getMapper(ProductMapper.class);
            int changed=pm.deleteById(1);
            session.commit();
            logger.info("Committed! Chenged Record Num="+changed);

            long endTime = System.currentTimeMillis();
            logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
        }catch(Exception ex) {
            logger.error("Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '"+ex.getMessage()+"'.");
            session.rollback();
            logger.info("Rollbacked.");
        }
        finally {
            session.close();
        }
    }

    // format seconds to day hour minute seconds style
    // Example 5000s will be formatted to 1h23m20s
    public static String toDhmsStyle(long allSeconds) {
        String DateTimes = null;

        long days = allSeconds / (60 * 60 * 24);
        long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
        long minutes = (allSeconds % (60 * 60)) / 60;
        long seconds = allSeconds % 60;

        if (days > 0) {
            DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
        } else if (hours > 0) {
            DateTimes = hours + "h" + minutes + "m" + seconds + "s";
        } else if (minutes > 0) {
            DateTimes = minutes + "m" + seconds + "s";
        } else {
            DateTimes = seconds + "s";
        }

        return DateTimes;
    }
}

Mapper接口类

package com.hy;

public interface ProductMapper {
    int deleteById(long id);
}

Mapper.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" >
<mapper namespace="com.hy.ProductMapper">
    <delete id="deleteById">
        delete from product where id=#{id}
    </delete>
</mapper>

用程序强行去删,会出现异常:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

执行下来,控制台输出会是:

 INFO [main] - Commit Status=false
ERROR [main] - Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orderTb`, CONSTRAINT `orderTb_ibfk_1` FOREIGN KEY (`productid`) REFERENCES `product` (`id`))
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: delete from product where id=?
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`orderTb`, CONSTRAINT `orderTb_ibfk_1` FOREIGN KEY (`productid`) REFERENCES `product` (`id`))'.
 INFO [main] - Rollbacked.

因此,在删除时,应该有选择地辨认并跳过这种异常才行。具体程序如下:

package com.hy;

import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;

public class DeleteProductTest2 {
    private static Logger logger = Logger.getLogger(DeleteProductTest2.class);

    public static void main(String[] args) throws Exception{
        long startTime = System.currentTimeMillis();
        Reader reader=Resources.getResourceAsReader("mybatis-config.xml");

        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(reader);
        reader.close();

        SqlSession session=ssf.openSession();
        logger.info("Commit Status="+session.getConnection().getAutoCommit());
        int totalChanged=0;

        try {
            ProductMapper pm=session.getMapper(ProductMapper.class);

            long[] arr= {1,2,3,4,5};
            for(long id:arr) {
                logger.info("deleteById id="+id+" started!");
                try {
                    int changed=pm.deleteById(id);
                    session.commit();
                    totalChanged+=changed;
                    logger.info("Committed! Chenged Record Num="+changed);
                }catch(Exception ex) {
                    if(ex.getMessage().contains("foreign key constraint fails")){ // 用 ex instanceof 识别不出来,故而用这种方式
                        logger.error("ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById("+id+")'.");
                        continue;
                    }else {
                        logger.error("Other Error/Exception happened when executing the meothod'ProductMapper.deleteById("+id+")' because '"+ex.getMessage()+"'.");
                        session.rollback();
                        logger.info("Rollbacked.");
                    }
                }

                logger.info("deleteById id="+id+" finished!");
            }
        }catch(Exception ex) {
            logger.error("Error/Exception happened when executing the meothod'ProductMapper.deleteById(1)' because '"+ex.getMessage()+"'.");
            session.rollback();
            logger.info("Rollbacked.");
        }
        finally {
            session.close();
        }

        logger.info("Changed recoed count="+totalChanged);
        long endTime = System.currentTimeMillis();
        logger.info("Time elapsed:" + toDhmsStyle((endTime - startTime)/1000) + ".");
    }

    // format seconds to day hour minute seconds style
    // Example 5000s will be formatted to 1h23m20s
    public static String toDhmsStyle(long allSeconds) {
        String DateTimes = null;

        long days = allSeconds / (60 * 60 * 24);
        long hours = (allSeconds % (60 * 60 * 24)) / (60 * 60);
        long minutes = (allSeconds % (60 * 60)) / 60;
        long seconds = allSeconds % 60;

        if (days > 0) {
            DateTimes = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
        } else if (hours > 0) {
            DateTimes = hours + "h" + minutes + "m" + seconds + "s";
        } else if (minutes > 0) {
            DateTimes = minutes + "m" + seconds + "s";
        } else {
            DateTimes = seconds + "s";
        }

        return DateTimes;
    }
}

执行后输出如下:

 INFO [main] - Commit Status=false
 INFO [main] - deleteById id=1 started!
ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(1)'.
 INFO [main] - deleteById id=2 started!
ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(2)'.
 INFO [main] - deleteById id=3 started!
ERROR [main] - ForeignKey collide Conflict happened when executing the meothod'ProductMapper.deleteById(3)'.
 INFO [main] - deleteById id=4 started!
 INFO [main] - Committed! Chenged Record Num=1
 INFO [main] - deleteById id=4 finished!
 INFO [main] - deleteById id=5 started!
 INFO [main] - Committed! Chenged Record Num=1
 INFO [main] - deleteById id=5 finished!
 INFO [main] - Changed recoed count=2
 INFO [main] - Time elapsed:10s.

--END-- 2019年10月6日14:52:46

[MySql]MySql中外键设置 以及Java/MyBatis程序对存在外键关联无法删除的规避的更多相关文章

  1. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  2. mysql级联更新的两种方式:触发器更新和外键

    1.mysql级联更新有两种方式:触发器更新和外键更新. 2.触发器更新和外键更新的目的都是为了保证数据完整性. 我们通常有这样的需求:删除表Table 1中记录,需要同时删除其它表中与Table 1 ...

  3. mysql概要(十四)(二)索引(补充:外键级联操作)

    [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | S ...

  4. Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了

    insertSelective---Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了 https://www.cnblogs.com/xi ...

  5. powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键

    转自:https://www.cnblogs.com/CoffeeHome/archive/2014/06/04/3767501.html 这里powerdesigner连接的数据库是以mysql为例 ...

  6. MySQL:如何导入导出数据表和如何清空有外建关联的数据表

    1.导入导出 导入数据库:前提:数据库和数据表要存在(已经被创建) (1)将数据表 test_user.sql 导入到test 数据库的test_user 表中 [root@test ~]# mysq ...

  7. java之hibernate之基于外键的双向一对一关联映射

    这篇讲解 基于外键的双向一对一关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系.表的设计 2.类结构 Person.java public class Person implements ...

  8. java之hibernate之基于外键的一对一单向关联映射

    这篇讲解基于外键的一对一单向关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系.表的设计 注意:基于外键的一对一关联的表结构和多对一的表结构是一致的,但是,外键是唯一的. 2.类的结构 Pe ...

  9. 一个7重嵌套表EF添加语句,注意子表赋值过程中只需写子表主键赋值,不需要写子表外键=父表主键。EF创建时会自动将子表外键设为与父表主键相等

    AIRPORT_HELIPORT tt = new AIRPORT_HELIPORT()            {                AIRPORT_HELIPORT_UUID = Gui ...

随机推荐

  1. mybatis整合spring下的的各种配置文件

    1.applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans ...

  2. echarts和v-chart使用心得

    echarts的响应式 每次窗口大小改变的时候都会触发onresize事件,这个时候我们将echarts对象的尺寸赋值给窗口的大小这个属性,从而实现图表对象与窗口对象的尺寸一致的情况window.on ...

  3. bootsctrap4 datepicker时间选择插件

    现在网上基本都是v3的时间选择插件,花了点时间改了找了个v4能用的 bootstrap-datepicker <!DOCTYPE html> <html> <head&g ...

  4. PHP中RabbitMQ之phpAmqplib实现(五

    本章讲诉如何使用php-amqplib实现RabbitMQ. 环境:CoentOS,PHP 7 简单介绍一下php-amqplib php-amqplib是Advanced Message Queui ...

  5. VUE【一、概述】

    早上写的忘了保存..还有很多唠叨的内容...哎又得重新写一遍..想吐槽那个自动保存有卵用.. 今天周一,早上起来继续 由于周六加了一整天班,导致周日无心学习,一天都在玩游戏看电影,到了晚上反而更加空虚 ...

  6. Vue介绍:vue导读1

    一.什么是vue 二.如何在页面中使用vue 三.vue的挂载点 四.vue的基础指令 一.什么是vue 1.什么是vue vue.js十一个渐进式javascript框架 渐进式:vue从控制页面中 ...

  7. 自己手写实现Dubbo

    目录 dubbo 简单介绍 为什么手写实现一下bubbo? 什么是RPC? 接口抽象 服务端实现 注册中心 消费者端: dubbo 简单介绍 dubbo 是阿里巴巴开源的一款分布式rpc框架. 为什么 ...

  8. JavaScript中定义类的方式详解

    本文实例讲述了JavaScript中定义类的方式.分享给大家供大家参考,具体如下: Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的exte ...

  9. MyBatis-08-使用注解开发

    8.使用注解开发 8.1.面向接口编程 面向接口编程的根本原因:解耦,可拓展,提高复用,分层开发中.上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性好 8.2.使用注解开发 注解在 ...

  10. 嵌入式系统FreeRTOS — 互斥信号量

    互斥信号量可以在资源保护的时候很有帮助.用于控制在两个或多个任务间访问共享资源.任务1里面用互斥,那么任务2只能等任务1访问完再访问同一个变量. 比如全局变量double gADC_value[CH_ ...