当前位置:   article > 正文

数据库多表操作事务处理_conn.preparestatement(sql); 事务的处理

conn.preparestatement(sql); 事务的处理

一、主要思路

在需要同时插入多条数据时,这其中可能是同一个表的多条记录,也可能是多个不同表之间的数据同时更新。对此,我们需要保证其中的原子性和一致性,做到要么全部操作都能全部成功完成,否则全部不操作。

我们可以通过SQL的事务来对相关数据库操作进行处理,在开始conn.setAutoCommit(false);(conn是或得的连接)把本次运行的SQL操作改为非自动运行,在配置好各SQL语句之后,调用conn.commit();来运行,其中通过try{……}catch……来捕捉异常,如果遇到错误时,就调用conn.rollback();来对本次操作进行回滚到操作前的状态,防止存在错误数据和脏数据。

二、主要实现方法

  1. /**
  2. * 批量插入对象-同一个表多条记录
  3. * <p>
  4. * 注意:对象字段不能为数据库关键字
  5. * @param list
  6. * @return
  7. * @throws SQLException
  8. * @author lims
  9. * @date 2015-08-28
  10. */
  11. public int[] insertSameTable(List<Pojo> list) throws SQLException {
  12. if (list == null || list.size() == 0) {
  13. return null;
  14. }
  15. String sql = getInsertSql(list.get(0));
  16. PreparedStatement ps = null;
  17. String[] fields = null;
  18. int[] result = null;
  19. Connection conn=getConnection();
  20. try {
  21. ps = conn.prepareStatement(sql.toString());
  22. this.startTransaction(conn);
  23. for (Pojo obj : list) {
  24. Map<String, String> pojo_bean = obj.listInsertableFields();
  25. fields = pojo_bean.keySet().toArray(
  26. new String[pojo_bean.size()]);
  27. for (int i = 0; i < fields.length; i++) {
  28. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  29. }
  30. ps.addBatch();
  31. }
  32. result = ps.executeBatch();
  33. this.commitTransaction(conn);
  34. } catch(Exception e){
  35. conn.rollback();
  36. throw new RuntimeException(e);
  37. } finally {
  38. fields = null;
  39. org.apache.commons.dbutils.DbUtils.closeQuietly(ps);
  40. this.closeConnection(conn);
  41. }
  42. return result;
  43. }
  44. /**
  45. * 批量插入对象-多表插入
  46. * <p>
  47. * 注意:对象字段不能为数据库关键字
  48. * @param list
  49. * @return
  50. * @throws SQLException
  51. * @author lims
  52. * @date 2015-08-28
  53. */
  54. public int insertMutilTable(List<Pojo> list) throws SQLException {
  55. if (list == null || list.size() == 0) {
  56. return 0;
  57. }
  58. String[] fields;
  59. PreparedStatement ps = null;
  60. int result = 0;
  61. Connection conn=getConnection();
  62. try {
  63. this.startTransaction(conn);
  64. for (Pojo obj : list) {
  65. Map<String, String> pojo_bean = obj.listInsertableFields();
  66. String sql = getInsertSql(obj);
  67. ps = conn.prepareStatement(sql.toString());
  68. fields = pojo_bean.keySet().toArray(
  69. new String[pojo_bean.size()]);
  70. for (int i = 0; i < fields.length; i++) {
  71. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  72. }
  73. result = ps.executeUpdate();
  74. }
  75. this.commitTransaction(conn);
  76. } catch(Exception e){
  77. conn.rollback();
  78. throw new RuntimeException(e);
  79. } finally {
  80. fields = null;
  81. org.apache.commons.dbutils.DbUtils.closeQuietly(ps);
  82. this.closeConnection(conn);
  83. }
  84. return result;
  85. }
  86. /**
  87. * 批量更新同一个表的多条记录
  88. * @param list
  89. * @return
  90. * @throws SQLException
  91. * @author lims
  92. * @date 2015-08-28
  93. */
  94. public int[] updateSameTable(List<Pojo> list) throws SQLException {
  95. if (list == null || list.size() == 0) {
  96. return null;
  97. }
  98. String[] fields;
  99. PreparedStatement ps = null;
  100. int[] result = null;
  101. Connection conn=getConnection();
  102. try {
  103. this.startTransaction(conn);
  104. for (Pojo obj : list) {
  105. Map<String, String> pojo_bean = obj.listInsertableFields();
  106. fields = pojo_bean.keySet().toArray(
  107. new String[pojo_bean.size()]);
  108. StringBuilder sql = new StringBuilder();
  109. sql.append("update "+getTableName(obj.getClass())+" set ");
  110. for (int i = 0; i < fields.length; i++) {
  111. if (i > 0)
  112. sql.append(',');
  113. sql.append(fields[i]).append(" = ? ");
  114. }
  115. sql.append(" where id=?");
  116. ps = conn.prepareStatement(sql.toString());
  117. fields = pojo_bean.keySet().toArray(
  118. new String[pojo_bean.size()+1]);
  119. for (int i = 0; i < fields.length; i++) {
  120. if(i==fields.length-1) {
  121. ps.setObject(i + 1, obj.getId());
  122. }
  123. else {
  124. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  125. }
  126. }
  127. ps.addBatch();
  128. }
  129. result = ps.executeBatch();
  130. this.commitTransaction(conn);
  131. } catch(Exception e){
  132. conn.rollback();
  133. throw new RuntimeException(e);
  134. } finally {
  135. ps.clearBatch();
  136. fields = null;
  137. org.apache.commons.dbutils.DbUtils.closeQuietly(ps);
  138. this.closeConnection(conn);
  139. }
  140. return result;
  141. }
  142. /**
  143. * 多表更新
  144. * @param list
  145. * @return
  146. * @throws SQLException
  147. * @author lims
  148. * @date 2015-08-28
  149. */
  150. public int updateMutilTable(List<Pojo> list) throws SQLException {
  151. if (list == null || list.size() == 0) {
  152. return 0;
  153. }
  154. String[] fields;
  155. PreparedStatement ps = null;
  156. int result = 0;
  157. Connection conn=getConnection();
  158. try {
  159. this.startTransaction(conn);
  160. for (Pojo obj : list) {
  161. Map<String, String> pojo_bean = obj.listInsertableFields();
  162. String sql = getUpdateSql(obj);
  163. ps = conn.prepareStatement(sql.toString());
  164. fields = pojo_bean.keySet().toArray(
  165. new String[pojo_bean.size()+1]);
  166. for (int i = 0; i < fields.length; i++) {
  167. if(i==fields.length-1) {
  168. ps.setObject(i + 1, obj.getId());
  169. }
  170. else {
  171. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  172. }
  173. }
  174. result = ps.executeUpdate();
  175. }
  176. this.commitTransaction(conn);
  177. } catch(Exception e){
  178. conn.rollback();
  179. throw new RuntimeException(e);
  180. } finally {
  181. fields = null;
  182. org.apache.commons.dbutils.DbUtils.closeQuietly(ps);
  183. this.closeConnection(conn);
  184. }
  185. return result;
  186. }
  187. /**
  188. * 插入数据和更新多表数据
  189. * @param list
  190. * @return
  191. * @throws SQLException
  192. * @author lims
  193. * @date 2015-08-28
  194. */
  195. public int insertAndUpdateMutilTable(List<Pojo> saveList,List<Pojo> updateList) throws SQLException {
  196. if (saveList == null || saveList.size() == 0 || updateList == null || updateList.size() == 0) {
  197. return 0;
  198. }
  199. String[] fields;
  200. PreparedStatement ps = null;
  201. int result = 0;
  202. Connection conn=getConnection();
  203. try {
  204. this.startTransaction(conn);
  205. for (Pojo obj : saveList) {//插入操作
  206. Map<String, String> pojo_bean = obj.listInsertableFields();
  207. String sql = getInsertSql(obj);
  208. ps = conn.prepareStatement(sql.toString());
  209. fields = pojo_bean.keySet().toArray(
  210. new String[pojo_bean.size()]);
  211. for (int i = 0; i < fields.length; i++) {
  212. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  213. }
  214. result = ps.executeUpdate();
  215. }
  216. for (Pojo obj : updateList) {//更新操作
  217. Map<String, String> pojo_bean = obj.listInsertableFields();
  218. String sql = getUpdateSql(obj);
  219. ps = conn.prepareStatement(sql.toString());
  220. fields = pojo_bean.keySet().toArray(
  221. new String[pojo_bean.size()+1]);
  222. for (int i = 0; i < fields.length; i++) {
  223. if(i==fields.length-1) {
  224. ps.setObject(i + 1, obj.getId());
  225. }
  226. else {
  227. ps.setObject(i + 1, pojo_bean.get(fields[i]));
  228. }
  229. }
  230. result = ps.executeUpdate();
  231. }
  232. this.commitTransaction(conn);
  233. } catch(Exception e){
  234. conn.rollback();
  235. throw new RuntimeException(e);
  236. } finally {
  237. fields = null;
  238. org.apache.commons.dbutils.DbUtils.closeQuietly(ps);
  239. this.closeConnection(conn);
  240. }
  241. return result;
  242. }

三、相关调用方法

  1. protected abstract Connection getConnection() throws SQLException;
  2. protected abstract void closeConnection(Connection conn);
  3. private void startTransaction(Connection conn) {
  4. try {
  5. if (conn != null) {
  6. conn.setAutoCommit(false);
  7. }
  8. } catch (Exception e) {
  9. throw new RuntimeException(e);
  10. }
  11. }
  12. private void commitTransaction(Connection conn) {
  13. try {
  14. if (conn != null) {
  15. conn.commit();
  16. }
  17. } catch (Exception e) {
  18. throw new RuntimeException(e);
  19. }
  20. }
  1. /**
  2. * 获取Pojo对应的数据库表名
  3. *
  4. * @param c
  5. * @return
  6. */
  7. private static <T extends Pojo> String getTableName(Class<T> c) {
  8. try {
  9. String tn = tableNameCache.get(c.getSimpleName());
  10. if (tn == null) {
  11. tn = c.newInstance().tableName();
  12. tableNameCache.put(c.getSimpleName(), tn);
  13. }
  14. return tn;
  15. } catch (Exception e) {
  16. log.error("Get " + c.getSimpleName() + " name exception.");
  17. return null;
  18. }
  19. }
  20. /**
  21. * 获取Pojo的插入sql语句
  22. *
  23. * @param obj
  24. * @return
  25. */
  26. private static String getInsertSql(Pojo obj) {
  27. try {
  28. String insertSql = insertSqlCache.get(obj.getClass().getName());
  29. if (insertSql == null) {
  30. Map<String, String> pojo_bean = obj.listInsertableFields();
  31. String[] fields = pojo_bean.keySet().toArray(
  32. new String[pojo_bean.size()]);
  33. StringBuilder sql = new StringBuilder("INSERT INTO ");
  34. sql.append(obj.tableName());
  35. sql.append('(');
  36. for (int i = 0; i < fields.length; i++) {
  37. if (i > 0)
  38. sql.append(',');
  39. sql.append(fields[i]);
  40. }
  41. sql.append(") VALUES(");
  42. for (int i = 0; i < fields.length; i++) {
  43. if (i > 0)
  44. sql.append(',');
  45. sql.append('?');
  46. }
  47. sql.append(')');
  48. insertSql = sql.toString();
  49. sql = null;
  50. insertSqlCache.put(obj.getClass().getName(), insertSql);
  51. }
  52. return insertSql;
  53. } catch (Exception e) {
  54. log.error("Get " + obj.getClass().getSimpleName()
  55. + " insertSql exception.");
  56. return null;
  57. }
  58. }
  59. /**
  60. * 获取Pojo的更新sql语句
  61. *
  62. * @param obj
  63. * @return
  64. * @author lims
  65. * @date 2015-08-23
  66. */
  67. private static String getUpdateSql(Pojo obj) {
  68. try {
  69. String updateSql = updateSqlCache.get(obj.getClass().getName());
  70. if (updateSql == null) {
  71. Map<String, String> pojo_bean = obj.listInsertableFields();
  72. String[] fields = pojo_bean.keySet().toArray(
  73. new String[pojo_bean.size()]);
  74. StringBuilder sql = new StringBuilder();
  75. sql.append("update "+getTableName(obj.getClass())+" set ");
  76. for (int i = 0; i < fields.length; i++) {
  77. if (i > 0)
  78. sql.append(',');
  79. sql.append(fields[i]).append(" = ? ");
  80. }
  81. sql.append(" where id=?");
  82. updateSql = sql.toString();
  83. sql = null;
  84. updateSqlCache.put(obj.getClass().getName(), updateSql);
  85. }
  86. return updateSql;
  87. } catch (Exception e) {
  88. log.error("Get " + obj.getClass().getSimpleName()
  89. + " updateSql exception.");
  90. return null;
  91. }
  92. }


四、上面用到的持久化基类

  1. import org.apache.commons.beanutils.BeanUtils;
  2. import java.io.Serializable;
  3. import java.util.Map;
  4. /**
  5. * 持久化基类
  6. */
  7. public abstract class Pojo implements Serializable {
  8. private static final long serialVersionUID = 1L;
  9. protected int id;
  10. public int getId() {
  11. return id;
  12. }
  13. public void setId(int id) {
  14. this.id = id;
  15. }
  16. public String tableName() {
  17. String tn=getClass().getSimpleName() ;
  18. if(tn.endsWith("Bean")) {
  19. tn=tn.substring(0,tn.length()-4);
  20. }
  21. tn = tn.toLowerCase();
  22. return tn;
  23. }
  24. protected String cacheRegion() {
  25. return this.getClass().getSimpleName();
  26. }
  27. /**
  28. * 列出要插入到数据库的字段集合,子类可以按照实际需求覆盖
  29. * @return
  30. */
  31. public Map<String, String> listInsertableFields() {
  32. try {
  33. Map<String, String> props = BeanUtils.describe(this);
  34. props.remove("id");
  35. props.remove("class");
  36. for(String s:props.keySet()){
  37. if(s.endsWith("_"))props.remove(s);
  38. }
  39. return props;
  40. } catch (Exception e) {
  41. throw new RuntimeException("Exception when Fetching fields of "
  42. + this);
  43. }
  44. }
  45. @Override
  46. public boolean equals(Object obj) {
  47. if (obj == null)
  48. return false;
  49. if (obj == this)
  50. return true;
  51. // 不同的子类尽管ID是相同也是不相等的
  52. if (!getClass().equals(obj.getClass()))
  53. return false;
  54. Pojo wb = (Pojo) obj;
  55. return wb.getId() == getId();
  56. }
  57. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/142119
推荐阅读
相关标签
  

闽ICP备14008679号