mybatis批量新增系列之无主键的表的批量新增
来源:互联网 发布:工作计划软件 编辑:程序博客网 时间:2024/06/06 01:37
在前面写了几篇批量新增的。虽然可以操作,但是很麻烦,每当对一个表进行批量插入的时候,就要在mapper文件中写一个语句,如果表的列名是有规律的还好说,写一个方法就可以拼接处sql语句,但是在很多时候,表中的列名往往是不规律的,故而很容易写错表名导致整个程序出错。最近查了下资料,终于找到了解决方案。
通过多次写sql,发现批量新增的语句中主要由两个sql语句组成
<insert id="batchDemo" parameterType="List">
<![CDATA[
${insertSql}
]]>
<foreach collection="list" item="obj" index="index" separator="union all">
${listSql}
</foreach>
</insert>
上面红色部分就是我们所需要拼接的
${insertSql}中包含的信息无非就是列名,表名, ${listSql}的信息就是列名和列所对应的类型
因为是批量新增,故传进来一个List ,一个表名,故而定义接口如下
public void batchInsertWithOutKey(List<DataRecord> list,String tableName);
接下来就是实现了:
第一步,通过表名查询相应的列名,类型
private List<DataRecord> getTableColumns(String tableName){
//查询表所包含的列名,以及该列对应的类型
Database db = DatabaseMetadataCache.getDatabase();
Table table=db.getTable(tableName);
//如果表不存在,直接返回空集合
if(table==null){
return new ArrayList<DataRecord>();
}
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;
}
相应的mapper文件中的sql如下
<select id="getTableColumn" parameterType="map" resultType="datarecord">
select column_name,data_type from user_tab_columns where table_name =#{tableName}
</select>
第二步将列名与类型放入一个map中
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")));
}
第三步就开始拼接字符串了
//现将DataRecord转换成Map
List<Map> back=new ArrayList<Map>();
for(DataRecord d:list){
back.add(d);
}
//如果back的个数大于0,获取第一个Map,因为List中的Map数据都是一个样
Map dm=back.get(0);
//dm中的key可以说是列名,value是相应的值,与我们查询到的列名可以对应起来,从而获取到其对应的类型,关键代码如下:
for(String colbjectKeys){
insertSql.append(""+col+",");
listSql.append("#{obj."+col+",jdbcType="+columnMap.get(col)+"}"+",");
}
//但是从数据库中查询到类型可能与我们listSql中所需要的类型不匹配,故而需要稍微转换一下:
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;
}
}
这个时候语句是拼接好了。怎么传入到mapper中又是一个问题,因为我们原先的是只传List,网上查询了一下foreach
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);
ok,基本上到这里就完了,以下是全部实现代码
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;
}
}
@Override
public void batchInsertWithOutKey(List<DataRecord> list,String tableName) {
//如果无数据,不需要执行插入了
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=new ArrayList<Map>();
for(DataRecord d:list){
back.add(d);
}
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:bjectKeys){
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);
}
mapper配置文件内容如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.mip.biz.syn.data.batch.demo">
<select id="getTableColumn" parameterType="map" resultType="datarecord">
select column_name,data_type from user_tab_columns where table_name =#{tableName}
</select>
<insert id="batchDemo" parameterType="List">
<![CDATA[
${insertSql}
]]>
<foreach collection="list" item="obj" index="index" separator="union all">
${listSql}
</foreach>
</insert>
</mapper>
至于有主键的批量插入下次再说
- mybatis批量新增系列之无主键的表的批量新增
- mybatis批量新增系列之有主键的表的批量新增
- mybatis批量新增系列之表的批量新增初探
- mybatis的批量新增
- mybatis的批量新增
- MyBatis的批量新增
- mybatis的批量新增
- mybatis的批量新增
- mybatis批量新增系列之类型处理
- mybatis批量新增,更新的一些问题
- mybatis 批量新增
- MyBatis批量新增、更新
- Mybatis批量新增,修改
- Mybatis批量新增
- Mybatis之批量新增数据(7)
- mysql的批量新增和批量修改
- mybatis 批量新增 插入 案例
- MyBatis批量新增和更新
- iOS中block实现的探究
- Hibernate缓存机制详解
- 外部系统调用规则引擎接口
- Kruskal+并查集
- .Net引用dll以后无法使用
- mybatis批量新增系列之无主键的表的批量新增
- 数据库专业词汇(中英对照)
- 微信公众平台申请消息接口–struts2(jsp)
- oracle包dbms_job的使用
- 《UNIX网络编程——Socket Networking API》(3rd,Vol1)读书笔记(1)【第一章】
- JavsScript变量作用域的小发现
- 【生活随笔】随笔一
- windows 核心编程之8 用户模式下的线程同步
- mysql 主从复制