[MySql]MySql中外键设置 以及Java/MyBatis程序对存在外键关联无法删除的规避
在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程序对存在外键关联无法删除的规避的更多相关文章
- Java MyBatis 插入数据库返回主键
最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...
- mysql级联更新的两种方式:触发器更新和外键
1.mysql级联更新有两种方式:触发器更新和外键更新. 2.触发器更新和外键更新的目的都是为了保证数据完整性. 我们通常有这样的需求:删除表Table 1中记录,需要同时删除其它表中与Table 1 ...
- mysql概要(十四)(二)索引(补充:外键级联操作)
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | S ...
- Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了
insertSelective---Java MyBatis 插入数据库返回主键--insertSelective这样就不用每次到数据库里面查询了 https://www.cnblogs.com/xi ...
- powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键
转自:https://www.cnblogs.com/CoffeeHome/archive/2014/06/04/3767501.html 这里powerdesigner连接的数据库是以mysql为例 ...
- MySQL:如何导入导出数据表和如何清空有外建关联的数据表
1.导入导出 导入数据库:前提:数据库和数据表要存在(已经被创建) (1)将数据表 test_user.sql 导入到test 数据库的test_user 表中 [root@test ~]# mysq ...
- java之hibernate之基于外键的双向一对一关联映射
这篇讲解 基于外键的双向一对一关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系.表的设计 2.类结构 Person.java public class Person implements ...
- java之hibernate之基于外键的一对一单向关联映射
这篇讲解基于外键的一对一单向关联映射 1.考察如下信息,人和身份证之间是一个一对一的关系.表的设计 注意:基于外键的一对一关联的表结构和多对一的表结构是一致的,但是,外键是唯一的. 2.类的结构 Pe ...
- 一个7重嵌套表EF添加语句,注意子表赋值过程中只需写子表主键赋值,不需要写子表外键=父表主键。EF创建时会自动将子表外键设为与父表主键相等
AIRPORT_HELIPORT tt = new AIRPORT_HELIPORT() { AIRPORT_HELIPORT_UUID = Gui ...
随机推荐
- K2 BPM_曾经我也是996的一员_全球领先的工作流引擎
最近关于996的工作模式掀起了新一波讨论热潮.事情源于有人在知名代码托管平台GitHub上,发起了一个名为“996.ICU”的项目,意为“工作996,生病ICU”,以抵制互联网公司的996工作制,项目 ...
- c# MVC方式文件上传
MVC控制器中代码 index.cshtml <form action="/Home/Upload" method="post" enctype=&quo ...
- Python3 GUI:PyQt5环境搭建
配置镜像源 最近用Python内置的Thinter写了个小工具,发现界面略朴素,于是决定转向PyQt5.先配置镜像源,否则只能龟速下载. C:\Users\你的用户名下新建目录pip 在pip目录下新 ...
- shiro系列三、ssm框架整合shiro实现权限控制
shiro权限框架是一个非常优秀的框架,前面的几篇文章对shiro进行了非常详细的介绍和原理分析,那么接下来让我们开始在web项目中使用它(javase也能用shiro): 一.数据库表结构设计 二. ...
- Linux克隆修改配置文件及IP
Linux下安装基本的开发软件比较费劲,特别是安装mysql的时候,这时候就需要学会克隆及直接备份base虚拟机了,下次直接打开,修改网卡文件信息就完事. 克隆虚拟机eth0网卡出现的问题解决1:修改 ...
- Cow Hopscotch (单调队列 + DP)
链接:https://ac.nowcoder.com/acm/contest/1113/K来源:牛客网 The cows have reverted to their childhood and ar ...
- Java web中不同浏览器间导出Excel文件名称乱码问题解决方案
问题描述: 对于不同浏览器存在对中文编码格式问题,从而在导出Excel文件时,中文文件名出现乱码的情况,即在程序中给要导出的文件指定一个中文名字时,在浏览器上出现的下载框中的文件名出现了乱码,解决如下 ...
- ACM-ICPC 2017 南宁赛区现场赛 M. The Maximum Unreachable Node Set(二分图)
题目链接:https://nanti.jisuanke.com/t/19979 题意:给出一个 n 个点,m 条边的 DAG,选出最大的子集使得其中结点两两不能到达. 题解:参考自:https://b ...
- 读取根目录src下的指定配置properties文件内容
代码如下: package com.chen.system.util; import java.io.File; import java.io.FileInputStream; import java ...
- vue项目更换目录后执行npm run dev 就报错(新手进)
在我们搭建好一个VUE项目的环境后,觉得这个项目存放的位置不好,想移动一下,但是移动后我们发现执行npm run dev就会报下面的错误: 明明只是移动了一下位置,就报错,实在是太恶心了. 但是只要我 ...