jdbctemplete 存在就更新不存在就插入的優化操作
阿新 • • 發佈:2018-12-11
當我們用java,jdbc 或者 spring的jdbctemplate來操作資料時候,總有時候會碰到 存在就插入不存在就更新 這樣的需求,我們一般都是用下面的方法解決
public void save(){ JdbcTemplate jdbc = getJdbc(); String updateStatement=""; String insertStatement=""; int cout = jdbc.update(updateStatement); if(count<=0){ //不存在需要被更新的資料,那就插入 jdbc.update(insertStatement); } jdbc.close(); }
在這裡僅僅只是一條資料,看著還行,但是如果是批量的資料呢?程式碼就會變成下面這樣
public void save(List<Param> list){ JdbcTemplate jdbc = getJdbc(); String updateStatement=""; String insertStatement=""; for(Param p:list){ int cout = jdbc.update(updateStatement); if(count<=0){ //不存在需要被更新的資料,那就插入 jdbc.update(insertStatement); } } jdbc.close(); }
這樣感覺就不怎麼好看了,而且效率也不怎麼樣。
優化方法如下:
1. 可以在資料庫中建立儲存過程,邏輯為單條記錄的 存在就更新不存在就插入;
2. 在java中通過jdbc呼叫儲存過程,如果是批量資料的話,跟批量插入差不多。
例項程式碼:
1. 儲存過程(postgres資料庫):
CREATE OR REPLACE FUNCTION insert_exists_device(p_deviceid integer, p_eventtype integer, p_state integer, p_eventvalue character varying) RETURNS integer AS $BODY$ BEGIN perform 1 FROM tablename WHERE deviceid=p_deviceid AND eventtype=p_eventtype; --判斷是否有該條記錄 IF NOT found THEN insertStatement; ELSE updateStatement; END IF; RETURN 1; END $BODY$ LANGUAGE plpgsql;
2. java中呼叫:
public void save(List<Param> list){ return jdbc.execute("{call insert_exists_device_monitor(?,?,?,?)}", new CallableStatementCallback<Boolean>() { @Override public Boolean doInCallableStatement(CallableStatement cs)throws SQLException, DataAccessException { for (Param p: list) { cs.setInt(1, deviceid); cs.setInt(2, p.getEventType()); cs.setInt(3, p.getState()); cs.setString(4, p.getEventValue()); cs.addBatch(); } s.executeBatch(); } }); }