前面介绍了无主键的表的批量插入, ​

但是在开发中往往许多的表是需要主键的,因而现在介绍一下有主键的表的批量插入,该主键是数据类型的数字类型。

最开始我是这么想的:主键让他自动添加,因而我们可以在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");

 }

}