[置顶] mybatis批量新增系列之有主键的表的批量新增
前面介绍了无主键的表的批量插入,文章地址:http://blog.csdn.net/zhouxiaoyun0228/article/details/9980181
但是在开发中往往许多的表是需要主键的,因而现在介绍一下有主键的表的批量插入,该主键是数据类型的数字类型。
最开始我是这么想的:主键让他自动添加,因而我们可以在insert中添加一个自增序列号就可以了,如下
<selectKey resultType="long" keyProperty="ID" order="BEFORE">
SELECT IBATIS_SEQUENCE.NEXTVAL AS ID FROM dual
</selectKey>
然后在listStr中添加一个#{obj.ID,jdbsType=DOUBLE}即可,但是发现没用,生成的Id不会自动添加进入List中。
后面有想了一下,其实思路还是没有错的。。我们只需要转化一下,将生成的主键Id值放入自动添加到List集合中即可,代码如下
for(DataRecord d:list){
Serializable id = this.generateId();
d.put(keyName, id);
back.add(d);
}
上面红色的标记是是与无主键部分唯一的区别,keyName是传入进来的主键名称,this.generateId();是提供自增长id的方法。
public Serializable generateId() {
return this.getDao().queryForLong("com.mip.biz.syn.data.batch.demo.getKeyValue", null);
}
mapper中的代码如下
<select id="getKeyValue" parameterType="map" resultType="LONG">
SELECT IBATIS_SEQUENCE.NEXTVAL AS ID FROM dual
</select>
这样一来也就解决了表有主键的问题。其他的代码没有变化,就是接口变化了一下:
/**
* 有主键的表批量插入
* @param list
* @param tableName
* @param keyName 主键名称
*/
public void batchInsertWithKey(List<DataRecord> list,String tableName,String keyName);
通过观察,发现代码好多冗余的,因而我们可以重构下代码,重构后的java代码如下,mapper中的代码不变,只添加了上面提到过的getKeyValue
接口方法:
/**
* 无主键的表批量插入
* @param list
* @param tableName
*/
public void batchInsertWithOutKey(List<DataRecord> list,String tableName);
/**
* 有主键的表批量插入
* @param list
* @param tableName
* @param keyName 主键名称
*/
public void batchInsertWithKey(List<DataRecord> list,String tableName,String keyName);
以下是实现方法 this.getDao().这里是内部封装的dao层,可以自己改动一下去实现与mapper交互
@Override
public void batchInsertWithKey(List<DataRecord> list,String tableName,String keyName) {
this.batchInsert(list, tableName, keyName);
}
@Override
public void batchInsertWithOutKey(List<DataRecord> list,String tableName) {
this.batchInsert(list, tableName, null);
}
//查询表所包含的列名,以及该列对应的类型
private List<DataRecord> getTableColumns(String tableName){
Map<String,Object> m=new HashMap<String,Object>();
m.put("tableName", tableName);
//去数据库中查询
List<DataRecord> list=this.getDao().queryForDataSet("com.mip.biz.syn.data.batch.demo.getTableColumn", m).getResults();
return list;
}
//改变列名对应的类型
private String changeColumnType(String dataType){
if("NUMBER".equals(dataType)){
return "DOUBLE";
}else if("VARCHAR2".equals(dataType)){
return "VARCHAR";
}else if(dataType.startsWith("TIMESTAMP")){
return "TIMESTAMP";
}else{
return dataType;
}
}
//根据是否有主键名改变集合的数据,DataRecord是Map的一个自定义的子类
private List<Map> changgeList(List<DataRecord> list,String keyName ){
List<Map> back=new ArrayList<Map>();
if(keyName==null){
for(DataRecord d:list){
back.add(d);
}
}else{
for(DataRecord d:list){
Serializable id = this.generateId();
d.put(keyName, id);
back.add(d);
}
}
return back;
}
//批量插入数据
private void batchInsert(List<DataRecord> list,String tableName,String keyName){
//如果无数据,不需要执行插入了
if(list.size()<=0){
return ;
}
//获取表的列名以及类型
List<DataRecord> columns=this.getTableColumns(tableName);
if(columns.size()==0){
return;
}
Map<String,String> columnMap=new HashMap<String,String>();
for(DataRecord dr:columns){
columnMap.put(dr.getString("COLUMN_NAME"), changeColumnType(dr.getString("DATA_TYPE")));
}
List<Map> back=this.changgeList(list, keyName);
Map dm=back.get(0);
Set<String> objectKeys = dm.keySet();
StringBuffer insertSql=new StringBuffer();
insertSql.append("insert into "+tableName+" (");
StringBuffer listSql=new StringBuffer();
listSql.append(" select ");
for(String col:objectKeys){
insertSql.append(""+col+",");
listSql.append("#{obj."+col+",jdbcType="+columnMap.get(col)+"}"+",");
}
// 删除最后的半角逗号
if (insertSql.length() > 0) {
insertSql.deleteCharAt(insertSql.length() - 1);
}
if (listSql.length() > 0) {
listSql.deleteCharAt(listSql.length() - 1);
}
insertSql.append(")");
listSql.append(" from dual");
Map<String,Object> batchMap=new HashMap<String,Object>();
batchMap.put("insertSql", insertSql.toString());
batchMap.put("listSql", listSql.toString());
batchMap.put("list", back);
this.getDao().insertByStatement("com.mip.biz.syn.data.batch.demo.batchDemo", batchMap);
}
//获取主键序列号
public Serializable generateId() {
return this.getDao().queryForLong("com.mip.biz.syn.data.batch.demo.getKeyValue", null);
}
public void test(){
//test_batch
List<DataRecord> list=new ArrayList<DataRecord>();
for(int i=0;i<10;i++){
DataRecord dr=new DataRecord();
dr.put("USERNAME","NAME_"+i);
list.add(dr);
}
batchInsertWithKey(list,"TEST_BATCH","ID");
}
}
[置顶] mybatis批量新增系列之有主键的表的批量新增的更多相关文章
- mybatis+sqlserver中返回非自增主键
首先把实体类贴出来(这里只贴出属性,其它的就是getter和setter方法): public class Around { private String xccd; //对应主键 ...
- Mybatis在insert操作时返回主键
今天在写项目的时候,遇到一个需求,就是在像数据库插入数据的时候,要保留插入数据的主键,以便后续进行级联时,可以将该主键作为另张表的外键. 但是在正常情况下我们使用插入语句返回的是int型,含义是影响该 ...
- mybatis与mysql插入时返回主键id的值
<insert id="insertCharge" parameterType="com.bb.bean.Rechargerecord"> < ...
- MyBatis面对Oracle数据库如何实现主键列自增长
因为Oracle数据库而言 不能够像SqlServer和MySql一样主键自增 而且MyBatis也没有提供直接的主键自增方法 所以我们自己使用查询语句来实现自增 实现代码: <insert i ...
- Mybatis批量插入返回自增主键(转)
我们都知道Mybatis在插入单条数据的时候有两种方式返回自增主键: 1.对于支持生成自增主键的数据库:useGenerateKeys和keyProperty. 2.不支持生成自增主键的数据库:< ...
- mybaits实现oracle批量新增数据,回填主键
项目有需求,百度了很久,反正他们说的方法,我都没成功,我也不知道是不是我写代码的姿势不正确,没办法只能自己想法子了 我们这个项目用到了通过Mapper,通用Mapper里通过OracleProvide ...
- mybatis用mysql数据库自增主键,插入一条记录返回新增记录的自增主键ID
今天在敲代码的时候遇到一个问题,就是往数据库里插入一条记录后需要返回这个新增记录的ID(自增主键), 公司框架用的是mybatis的通用Mapper接口,里面的插入方法貌似是不能把新纪录的ID回填到对 ...
- mybatis注解版in查询、字符串判空模糊匹配 、批量插入、插入返回主键
IN查询 @Select({"<script> " + " select * "+ " from business_threat bt \ ...
- 深入分析Mybatis 使用useGeneratedKeys获取自增主键
摘要 我们经常使用useGenerateKeys来返回自增主键,避免多一次查询.也会经常使用on duplicate key update,来进行insertOrUpdate,来避免先query 在i ...
随机推荐
- Glog
Glog的简单入门,glog虽然在配置参数方面比较麻烦,但是在小规模程序中,由于其简单灵活,也许会有优势. 0, glog 是google的开源日志系统,相比较log4系列的日志系统,它更加轻巧灵活 ...
- BootStrap 智能表单系列 五 表单依赖插件处理
这一章比较简单哦,主要就是生产表单元素后的一些后续处理操作,比如日期插件的渲染.一些autocomplete的处理等,在回调里面处理就可以了, demo: $("input.date-pic ...
- ios开发学习笔记(1)
objective-c基础总结 第一二章 1.application:didiFinishLauchingWithOptions:程序启动后立即执行 2.启动界面代码格式:self.window = ...
- sql 月初和月末
--月初 select convert(varchar(10),dateadd(day,-(day(getdate()) -1),getdate()) ,120) --月末select conve ...
- [Swust OJ 589]--吃西瓜(三维矩阵压缩)
题目链接:http://acm.swust.edu.cn/problem/589/ Time limit(ms): 2000 Memory limit(kb): 65535 Description ...
- 关于tomcat的clean
1 添加了一个web项目到tomcat,然后进行clean的时候,根目录实际上是在WebContent下,也就是说存放在WebContent目录下的所有文件在clean的时候才会被添加到tomcat对 ...
- INDEX相关
1.索引应该建立在WHERE子句经常用到的表列上,如果在大表上频率使用某列或者某几列作为条件执行检索操作,并且检索的行数低于总行数的15%,那么应该考虑在该几行上添加索引. 2.为了提高多表连接的性能 ...
- poj 3185 The Water Bowls 高斯消元枚举变元
题目链接 给一行0 1 的数, 翻转一个就会使他以及它左右两边的都变, 求最少多少次可以变成全0. 模板题. #include <iostream> #include <vector ...
- float编码杂谈
浮点数的编码转换采用的是IEEE规定的编码标准,float和double 这两种类型的数据的转换原理相同,但是由于范围不一样,编码方式有些区别.IEEE规定的编码会将一个浮点数转换为二进制数.以科学计 ...
- 转: Transact-sql游标使用详解~~很详细
/*原理:游标就是把数据按照指定要求提取出相应的数据集,然后逐条进行数据处理.1.1游标的概念 游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集. 使用游标(cursor)的一 ...