Java開發經驗分享之通過MyBatis編寫一個批量插入,局部更新的方法。(本作品為原創,如有不足之處,還望大牛多給意見。如需轉載,請注明出處。謝謝!)
一、有MyBatis開發經驗的小伙伴都知道,在MyBatis中的在SqlSession接口中包含了所有可能執行的sql語句,我這里就不一一列舉,想了解的小伙伴請參考org.apache.ibatis.session.SqlSession源碼。今天我們主要實現一個 批量插入數據操作 與 局部更新數據操作,只更新前端傳過來字段的值。
說明:
話不多說,直接上代碼。
Dao層實現:也是通過SqlSession 來實現這一操作。
public class BaseDaoImp<T> implements IBaseDao<T> { protected static Log logger = LogFactory.getLog(BaseDaoImp.class); /** * 預定義的statement */
protected static final String INSERT_BACTH = "insertBatch";
protected static final String UPDATE_LOCAL = "updateLocal";
protected static final String ERROR_NULL_PAREM = "參數為空,請檢查!";
protected static final String ERROR_INSERT = "插入數據發生異常,請重試!"; protected static final String ERROR_UPDATE = "更新數據發生異常,請重試!";
protected static final String DOT = "."; protected Class<T> entityClass = null; @Autowired protected SqlSessionTemplate sqlSession; @SuppressWarnings("unchecked") public BaseDaoImp() { entityClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; } protected String getPrefix() { return entityClass.getSimpleName() + DOT; } public SqlSession getSqlSession() { return sqlSession; } public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; }
/* * 局部更新,只更新前端傳過來字段的值 */ public int updateLocal(Map<String, Object> params) { if (null == params) { logger.error(ERROR_NULL_PAREM); throw new ServiceException(ResultCode.FAILURE_302, ERROR_NULL_PAREM); } try { return sqlSession.update(UPDATE_LOCAL, params); } catch (ServiceException e) { throw new ServiceException(ResultCode.FAILURE_302, ERROR_UPDATE); } }
/** * 批量插入 */ public int insertBatch(List<T> list) { if (null == list || list.size() == 0) { logger.error(ERROR_NULL_PAREM); throw new ServiceException(ResultCode.FAILURE_302, ERROR_NULL_PAREM); } int result = 1; SqlSession batchSqlSession = null; try { batchSqlSession = sqlSession.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);// 獲取批量方式的sqlsession int batchCount = 1000;// 每批commit的個數 int batchLastIndex = batchCount;// 每批最后一個的下標 for (int index = 0; index < list.size();) { if (batchLastIndex >= list.size()) { batchLastIndex = list.size(); result += batchSqlSession.insert(getPrefix() + INSERT_BACTH,list.subList(index, batchLastIndex)); batchSqlSession.commit(); System.out.println("index:" + index + " batchLastIndex:" + batchLastIndex); break;// 數據插入完畢,退出循環 } else { result += batchSqlSession.insert(getPrefix() + INSERT_BACTH,list.subList(index, batchLastIndex)); batchSqlSession.commit(); System.out.println("index:" + index + " batchLastIndex:" + batchLastIndex); index = batchLastIndex;// 設置下一批下標 batchLastIndex = index + (batchCount - 1); } } batchSqlSession.commit(); return result; } catch (ServiceException e) { throw new ServiceException(ResultCode.FAILURE_302, ERROR_INSERT); } finally { batchSqlSession.close(); } }
}
XML代碼實現如下:
局部更新操作:
<!-- 局部更新操作 -->
<update id="updateLocal" parameterType="java.util.Map">
UPDATE TABLE SET
<foreach collection="params.keys" item="key" index="index"
separator=",">
<!-- 將對應的value賦值給對應的Key(key和數據庫的字段一樣) -->
<if test="key != 'FD_ID'">
${key}=#{params[${key}]}
</if>
</foreach>
<!--#{1}表示接受Dao層方法傳入的第二個參數 -->
where FD_ID = #{params[FD_ID]}
</update>
批量插入數據操作:
<!-- 批量插入數據操作 -->
<insert id="insertBatch" parameterType="java.util.List"> insert into TABLE (Field_1,
Field_2,
Field_3, Field_4 ) select t.* from ( <foreach collection="list" item="item" index="index" separator="UNION ALL"> (SELECT #{item.field1,jdbcType=VARCHAR}, #{item.field2,jdbcType=VARCHAR}, #{item.field3,jdbcType=VARCHAR}, #{item.field4,jdbcType=VARCHAR} FROM dual) </foreach> ) t </insert>
