以下讨论全部针对Mysql数据库:)
通常业务上至少需要两种类型的不重复插入记录的需求:
- 如果某些关键字段已经在Mysql中存在了,不要重复插入,而是改为更新某些字段。
- 如果某些关键字段已经在Mysql中存在了,不要重复插入,也不需要做更新操作,直接忽略即可。
1、针对上面的第一种,mysql提供了insert into ... on duplicate key update ... 语法(Mysql自己的语法,不属于标准SQL)来实现。这种场景相对常见。使用的前提是,需要定义主键或者唯一性索引,用来告诉Mysql哪些字段的重复会造成主键冲突或者违背唯一性约束条件。当这些情况出现时,就放弃insert操作,转而执行后面的update操作。上一个具体的例子,在ibatis中写的一个上面逻辑的sql:
<statement id="testInsertOnDuplicateKeyUpdate"
parameterClass="com.alibaba.ais.bdc.person.dataobject.UserInfo">
<!--Here the employ_id has been defined as a primary key-->
insert into T_USER_INFO (employ_id,fans_count,follow_count)
values (#employId#,#fansCount#,#followCount#)
ON DUPLICATE KEY UPDATE follow_count=follow_count+1
</statement>
上面的插入操作就会在employ_id发生主键冲突的时候,转变为更新follow_count字段(自增一个单位)。
2、针对上面的第二种,mysql提供了insert ignore into ... 语法(Mysql自己的语法,不属于标准SQL)来实现。这种场景相对要少见一些。 使用的前提是,需要定义主键或者唯一性索引,原因同上面一致。但不同的就是,违背唯一性约束时,直接忽略这次insert操作,然后啥也不干了,也不会报错。。。
但这里有个问题,就是有时业务本身还是需要知道语句到底执行了insert还是没有执行!因为需要根据这个反馈信息,做出不同的处理逻辑。这里给出使用ibatis时,两种不同的处理方法。
- 借助mysql的内置函数row_count()和ibatis的selectKey标签:
- 关于ibatis的selectKey标签,更为常见的用法是在插入对象到DB之后,返回DB自增产生的主键ID。比如:
-
<insert id="testSelectKey">
insert into T_TEST(WATCHER, WATCHEE) values (#watcher#,#watchee#)
<selectKey resultClass="int" keyProperty="id">
select last_insert_id() as ID from dependency limit 1
</selectKey>
</insert>
- 通过上面语句进行插入操作之后,可以通过如下方式在Java代码中获得这个DB自增产生的ID:
-
Integer id = (Integer) sqlMapClient.insert("testSelectKey", param);
- row_count()是Mysql提供可以获得insert、update、delete这几种操作成功处理行数的一个内置函数,有了这个函数,再结合上面给出的selectKey标签的例子,就可以做到获得insert ignore时,成功insert的行数。有了这个行数,也就知道了到底有没有发生insert操作。(发生了插入操作该函数返回值会大于0),于是改编一下上面的sql-map中的sql(注意其中的ignore关键字):
-
<insert id="testInsertIgnore">
insert ignore into T_TEST(WATCHER, WATCHEE) values (#watcher#,#watchee#)
<selectKey resultClass="int" keyProperty="id">
select row_count() as ID from T_USER_RELATION limit 1
</selectKey>
</insert>
通过上面语句进行插入操作之后,可以通过如下方式在Java代码中获得insert真正影响到的行数:
-
Integer affectedRows = (Integer)sqlMapClient.insert("testInsertIgnore", param);
- 利用ibatis的update语句:上面之所以要费劲周折的修改insert语句,时因为ibatis本身的insert不是默认支持返回影响的行数的。但是update语句支持!于是,另外一个思路,就是利用update语句来完成这个insert操作。
-
<update id="testInsertIgnore">
insert ignore into T_USER_RELATION(WATCHER, WATCHEE) values (#watcher#,#watchee#)
<!--Without selectKey tag, it looks mush more concise-->
</update>
通过上面语句进行插入操作之后,可以通过如下方式在Java代码中获得insert真正影响到的行数(这里需要注意的是,Java代码中需要使用sqlMapClient的update的API哦):
-
Integer affectedRows = (Integer)sqlMapClient.update("testInsertIgnore", param);
分享到:
相关推荐
C#中iBatis连接mySQL使用的DLL
Spring + Ibatis 与mysql集群集成
ibatismysql.jar ibatismysql.jar
ibatis +mysql 实例 :是一个web项目 (简单的增删改查)
初学ibatis 自己实现的一个简单的ibatis查询mysql的文档,内容不是很多,但是对学习来说很有帮助,关于配置文件及整个项目工程的结构一目了然,这是在eclipse下实现的
Ibatis连接MySQL数据库实例 有代码 项目下下来直接跑就行了,不过要修改数据库配置信息哦 跑不起来我吃翔三斤
本工程用于研究Ibatis和MySQL结合使用的方法 本工程编码方式:UTF-8 须执行的SQL语句: CREATE DATABASE `test`; USE `test`; DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` char(36) NOT NULL...
ibatis操作mysql
目前网上罕见的JSF+iBATIS+MySQL示例代码,公司某软件项目所需而做的前期DEMO,只有两个Web页面,用户登录和用户列表,但已经能够说明JSF+iBATIS的典型应用方式。 MyEclipse6.5 项目工程文件,内含SQL建库指令。 ...
velocity+ibatis+mysql+exlipse实例 velocity+ibatis+mysql+exlipse实例 velocity+ibatis+mysql+exlipse实例 velocity+ibatis+mysql+exlipse实例 velocity+ibatis+mysql+exlipse实例
struts spring ibatis mysql 分页,增删改查,以及导出excle
struts2+spring+ibatis+mysql AOP日志管理,异常捕获 tomcat6.0+jdk1.6
通过foreach实现ibatis的批量插入
通过Ibatis3xml文件配置+Mysql实现数据批量插入,原先在网上找很多,都是关于批量更新,批量插入的很少,而且其写法又完全不同,所以自己研究了一下。可供参考。另外插入时如出现内容报错,请参照my.cnf修改书库配置...
ibatis实现原理解析
iBatis操作MySQL增删改查,亲测可用,附带sql文件,完全配置,增加记录,删除指定记录以及全部记录,查询全部记录以及指定记录,更新记录等操作
mysql最新驱动程序,用于JDBC连接. mysql-connector-java-5.1.6-bin.jar ibatis-2.3.0.677 jar包持久层框架ibatis所需引入的jar包
springMVC和ibatis实现sql2005数据库插入案例
该资源适合准备接触,或者新接触的小伙伴使用,欢迎交流吐槽!
该项目框架springmvc+ibatis+mysql,同时包括quartz实现定时器任务。