基于mybatis動態(tài)拼接SQL實現(xiàn)批量存儲

最近公司有個需求就是將excel的數(shù)據(jù)存儲到數(shù)據(jù)庫,不過數(shù)據(jù)庫有三百多張表馍乙,不同的excel存在不同的表中侨艾,如果每張表都建個實體去映射需要建三百多個實體,代碼大量重復不說羡滑,工程量太大菇爪,所以想到去動態(tài)拼接sql,批量上傳柒昏。持久層框架選擇了強大的mybatis凳宙,因為動態(tài)拼接,不采用預編譯职祷,變量用${}代替氏涩。
將excel文件名和對應數(shù)據(jù)庫表名存儲在一張表里,每次導入時候先去查找相應表名有梆。再根據(jù)表名查找表所有的字段名(通過MetaData)是尖。
自己建一個轉化工具類:

@Slf4j
@Component
public class GetCuloumListUtil {
    @Value("${spring.datasource.url}")
    private String datasource;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;

    public List<String> getCuloumList(String tableName) throws SQLException {

        List<String> list = null;

            Connection conn = DriverManager
                    .getConnection(datasource+"?user="+username+"&password="+password);
            DatabaseMetaData metaData = conn.getMetaData();
            ResultSet resultSet = metaData.getColumns(null, "%", tableName, "%");
            list = new ArrayList<>();
            while (resultSet.next()) {
                String columnName = resultSet.getString("COLUMN_NAME");
                list.add(columnName);
            }

        log.info(tableName+"表字段名:{}", list.toString());
        return list;
    }

}

由于動態(tài)構建sql不創(chuàng)建實體,所以將讀取每一列的值放到一個map中泥耀,key是列的序號析砸,value是列的值,由于要求map中值有序爆袍,所以采用TreeMap實例化首繁。讀取的每一行是一個map,再將每一行的map放到一個list中陨囊。poi導入就不介紹了弦疮,這里部分代碼如下:

for(int r=1;r<totalRows;r++){
            Map<Integer,String> map=new TreeMap();//要求map有序
            Row row = sheet.getRow(r);
            if (row == null) continue;

            //循環(huán)Excel的列
            for(int c = 0; c <this.totalCells; c++){

                if(row.getCell(c)!=null&&!row.getCell(c).equals("")){
                    if (row.getCell(c).getCellType()== HSSFCell.CELL_TYPE_NUMERIC){
                        log.info("cell類型是:{}",row.getCell(c).getCellStyle().getDataFormatString());
                        if(HSSFDateUtil.isCellDateFormatted(row.getCell(c))){//時間類型的列
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date date = HSSFDateUtil.getJavaDate(row.getCell(c).getNumericCellValue());
                            map.put(c,dateFormat.format(date));
                        }else {
                            row.getCell(c).setCellType(Cell.CELL_TYPE_STRING);
                            map.put(c,row.getCell(c).getStringCellValue());
                        }
                    }else {
                        row.getCell(c).setCellType(Cell.CELL_TYPE_STRING);//列類型轉為String
                        map.put(c,row.getCell(c).getStringCellValue());//列值存在map中
                    }
                }else {
                    map.put(c,"");
                }
            }
            list.add(map);
        }

mapping.xml配置文件:

<insert id="add">
    INSERT INTO ${tableName}
    <foreach collection="culoum" item="item" separator="," open="(" close=")">
        ${item}
    </foreach>
    VALUES
    <foreach collection="value" item="list" separator=",">

       <foreach collection="list.values" item="val" separator="," open="(" close=")">
         '${val}'
       </foreach>
    </foreach>
</insert>

這里采用了嵌套foreach循環(huán),里面的collection可以直接用list.values取出map的value值蜘醋,如果想取出map的key值可以用list.key胁塞,這也是mybatis的強大之處啊。
dao層代碼:

  void add(@Param("tableName") String tableName, @Param("culoum") List culoum, @Param("value") List<Map<Integer, String>> value);

注意:
1、由于動態(tài)sql沒有采用預編譯啸罢,所以需要我們手動處理sql注入的問題编检。
2、由于mysql默認接受data最大是1M扰才,也就是超過了就會失敗允懂。所以excel文件過大時候要設置max_allow_packet。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末衩匣,一起剝皮案震驚了整個濱河市蕾总,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌琅捏,老刑警劉巖生百,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柄延,居然都是意外死亡蚀浆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門搜吧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來市俊,“玉大人,你說我怎么就攤上這事赎败。” “怎么了蠢甲?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵僵刮,是天一觀的道長。 經(jīng)常有香客問我鹦牛,道長搞糕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任曼追,我火速辦了婚禮窍仰,結果婚禮上,老公的妹妹穿的比我還像新娘礼殊。我一直安慰自己驹吮,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布晶伦。 她就那樣靜靜地躺著碟狞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪婚陪。 梳的紋絲不亂的頭發(fā)上族沃,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音,去河邊找鬼脆淹。 笑死常空,一個胖子當著我的面吹牛,可吹牛的內容都是我干的盖溺。 我是一名探鬼主播漓糙,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咐柜!你這毒婦竟也來了兼蜈?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拙友,失蹤者是張志新(化名)和其女友劉穎为狸,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遗契,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡辐棒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了牍蜂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漾根。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鲫竞,靈堂內的尸體忽然破棺而出辐怕,到底是詐尸還是另有隱情,我是刑警寧澤从绘,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布寄疏,位于F島的核電站,受9級特大地震影響僵井,放射性物質發(fā)生泄漏陕截。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一批什、第九天 我趴在偏房一處隱蔽的房頂上張望农曲。 院中可真熱鬧,春花似錦驻债、人聲如沸乳规。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽青扔。三九已至微猖,卻和暖如春凛剥,著一層夾襖步出監(jiān)牢的瞬間犁珠,已是汗流浹背犁享。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工桨吊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凤巨,地道東北人敢茁。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓伸刃,卻偏偏與公主長得像奕枝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子郎笆,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容