• [置顶] 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");
     }
    }

  • 相关阅读:
    好用的镜头站下载工具
    300+Jquery, CSS, MooTools 和 JS的导航菜单资源
    股票入门2
    MEF学习笔记(6):出口和元数据
    MEF学习笔记(5):迟延加载导出部件
    WinForm控件复杂数据绑定常用数据源(如:Dictionary)(对Combobox,DataGridView等控件DataSource赋值的多种方法)
    wpf 多线程绑定控件
    HTTP 错误 404.2 Not Found 由于 Web 服务器上的“ISAPI 和 CGI 限制”列表设置,无法提供您请求的页面
    ADODB.Stream 错误 '800a0bbc' 写入文件失败。
    'System.Windows.StaticResourceExtension' threw an exception
  • 原文地址:https://www.cnblogs.com/riskyer/p/3260416.html
Copyright © 2020-2023  润新知