在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

基于JDBC的数据库DAO封装

2016-7-29 15:47| 发布者: zhangjf| 查看: 691| 评论: 0

摘要: 基于JDBC的数据库DAO封装, MYSQL 版本 。可与下面的代码配合比较: 基于Apache Dbutils 的数据库DAO封装地址: http://www.oschina.net/code/snippet_2688496_55658 import java.sql.Connectio ...
基于JDBC的数据库DAO封装, MYSQL 版本 。
可与下面的代码配合比较:
基于Apache Dbutils 的数据库DAO封装
地址: http://www.oschina.net/code/snippet_2688496_55658
  1. import java.sql.Connection;
  2. import java.sql.PreparedStatement;
  3. import java.sql.ResultSet;
  4. import java.sql.ResultSetMetaData;
  5. import java.sql.SQLException;
  6. import java.util.ArrayList;
  7. import java.util.Collections;
  8. import java.util.LinkedHashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.ResourceBundle;
  12. import java.util.concurrent.ExecutionException;
  13. import org.apache.commons.lang.StringUtils;
  14. import org.apache.commons.lang.builder.ToStringBuilder;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  18. /**
  19. *
  20. * 带事务支持的数据库操作DAO实现类
  21. *
  22. * @author 00fly
  23. * @version [版本号, 2016-3-5]
  24. * @see [相关类/方法]
  25. * @since [产品/模块版本]
  26. */
  27. public class BaseDAOImpl
  28. {
  29. Logger log = LoggerFactory.getLogger(getClass());
  30. // 使用ThreadLocal存储当前线程中的Connection对象
  31. private ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
  32. private static MysqlDataSource dataSource = new MysqlDataSource();
  33. // 静态初始化 DataSource
  34. static
  35. {
  36. ResourceBundle config = ResourceBundle.getBundle("jdbc");
  37. dataSource.setUrl(config.getString("jdbc.url"));
  38. dataSource.setUser(config.getString("jdbc.username"));
  39. dataSource.setPassword(config.getString("jdbc.password"));
  40. }
  41. /**
  42. * 获取数据库连接
  43. *
  44. * @return
  45. * @throws ExecutionException
  46. * @throws InterruptedException
  47. * @see [类、类#方法、类#成员]
  48. */
  49. protected Connection getConnection()
  50. {
  51. Connection connection = threadLocal.get();
  52. try
  53. {
  54. if (connection == null)
  55. {
  56. // 把 connection绑定到当前线程上
  57. connection = dataSource.getConnection();
  58. threadLocal.set(connection);
  59. }
  60. }
  61. catch (Exception e)
  62. {
  63. log.error(e.getMessage());
  64. throw new RuntimeException("Failed to get Mysql connection");
  65. }
  66. return connection;
  67. }
  68. /**
  69. * SQl查询,返回执行结果
  70. *
  71. * @param sql 查询sql
  72. * @return
  73. * @throws SQLException
  74. * @see [类、类#方法、类#成员]
  75. */
  76. public List<Map<String, Object>> querySql(String sql)
  77. throws SQLException
  78. {
  79. return querySql(sql, null);
  80. }
  81. /**
  82. * 带可变参数查询,返回执行结果
  83. *
  84. * @param sql 查询sql
  85. * @param para 可变参数
  86. * @return
  87. * @throws SQLException
  88. */
  89. public List<Map<String, Object>> querySql(String sql, Object[] para)
  90. throws SQLException
  91. {
  92. log.info("querySql: {}, para: {}", sql, ToStringBuilder.reflectionToString(para));
  93. Connection conn = null;
  94. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  95. try
  96. {
  97. conn = getConnection();
  98. if (conn != null)
  99. {
  100. PreparedStatement ps = conn.prepareStatement(sql);
  101. ResultSet rs = null;
  102. if (null != para && para.length > 0)
  103. {
  104. for (int i = 0; i < para.length; i++)
  105. {
  106. ps.setObject(i + 1, para[i]);
  107. }
  108. }
  109. rs = ps.executeQuery();
  110. ResultSetMetaData md = rs.getMetaData();
  111. int columnCount = md.getColumnCount(); // Map rowData
  112. while (rs.next())
  113. {
  114. Map<String, Object> rowData = new LinkedHashMap<String, Object>();
  115. for (int i = 1; i <= columnCount; i++)
  116. {
  117. rowData.put(md.getColumnName(i).toLowerCase(), rs.getObject(i));
  118. }
  119. list.add(rowData);
  120. }
  121. ps.close();
  122. rs.close();
  123. }
  124. }
  125. catch (SQLException e)
  126. {
  127. log.error("--------- QuerySql--" + e.getMessage());
  128. throw e;
  129. }
  130. finally
  131. {
  132. if (conn != null && conn.getAutoCommit() == true)
  133. {
  134. freeConnection();
  135. }
  136. log.info("BaseDAOImpl querySql end ");
  137. }
  138. return list;
  139. }
  140. /**
  141. * 带可变参数条件的分页查询
  142. *
  143. * @param sql 查询sql
  144. * @param pageNo 页号
  145. * @param pageSize 每页记录数
  146. * @param para 可变参数
  147. * @return
  148. * @throws SQLException
  149. * @see [类、类#方法、类#成员]
  150. */
  151. public PaginationSupport queryForPagination(String sql, int pageNo, int pageSize, Object[] para)
  152. throws SQLException
  153. {
  154. // 保证正整数
  155. pageNo = Math.max(pageNo, 1);
  156. pageSize = Math.max(pageSize, 1);
  157. // 查询记录总条数
  158. int index = sql.toLowerCase().indexOf(" from ");
  159. String countSql = "select count(1)" + StringUtils.substring(sql, index);
  160. long total = queryForLong(countSql, para);
  161. // 查询当前页数据
  162. StringBuffer sbSql =
  163. new StringBuffer(sql).append(" limit ").append(pageSize * (pageNo - 1)).append(", ").append(pageSize);
  164. List<Map<String, Object>> list = querySql(sbSql.toString(), para);
  165. // 封装返回分页对象
  166. PaginationSupport page = new PaginationSupport(total, pageNo, pageSize);
  167. page.setItems(list);
  168. return page;
  169. }
  170. public Long queryCountSql(String countSql)
  171. throws SQLException
  172. {
  173. return queryCountSql(countSql, null);
  174. }
  175. /**
  176. * 带可变参数查询,返回记录条数
  177. *
  178. * @param countSql 查询记录条数的sql
  179. * @param para 可变参数
  180. * @return
  181. * @throws SQLException
  182. */
  183. public Long queryCountSql(String countSql, Object[] para)
  184. throws SQLException
  185. {
  186. log.info("queryCountSql: {}, para: {}", countSql, ToStringBuilder.reflectionToString(para));
  187. Long count = null;
  188. Connection conn = null;
  189. try
  190. {
  191. conn = getConnection();
  192. if (conn != null)
  193. {
  194. PreparedStatement ps = conn.prepareStatement(countSql);
  195. ResultSet rs = null;
  196. if (null != para && para.length > 0)
  197. {
  198. for (int i = 0; i < para.length; i++)
  199. {
  200. ps.setObject(i + 1, para[i]);
  201. }
  202. }
  203. rs = ps.executeQuery();
  204. while (rs.next())
  205. {
  206. count = rs.getLong(1);
  207. }
  208. ps.close();
  209. rs.close();
  210. }
  211. }
  212. catch (SQLException e)
  213. {
  214. log.error("--------- queryCountSql--" + e.getMessage());
  215. throw e;
  216. }
  217. finally
  218. {
  219. if (conn != null && conn.getAutoCommit() == true)
  220. {
  221. freeConnection();
  222. }
  223. log.info("BaseDAOImpl queryCountSql end ");
  224. }
  225. return count;
  226. }
  227. /**
  228. * 带可变参数查询,返回long类型数据
  229. *
  230. * @param sql 查询sql
  231. * @param para 可变参数
  232. * @return
  233. * @throws SQLException
  234. */
  235. public Long queryForLong(String sql, Object[] para)
  236. throws SQLException
  237. {
  238. return queryCountSql(sql, para);
  239. }
  240. /**
  241. * 带可变参数查询,返回首条执行结果
  242. *
  243. * @param sql 查询sql
  244. * @param para 可变参数
  245. * @return
  246. * @throws SQLException
  247. */
  248. public Map<String, Object> queryFirst(String sql, Object[] para)
  249. throws SQLException
  250. {
  251. if (!sql.contains(" limit ")) // 前后有空格
  252. {
  253. sql = sql + " limit 1";
  254. }
  255. List<Map<String, Object>> list = querySql(sql, para);
  256. if (list.isEmpty())
  257. {
  258. return Collections.emptyMap();
  259. }
  260. return list.get(0);
  261. }
  262. /**
  263. * 带可变参数, 执行sql插入,返回新增记录的自增主键<BR>
  264. * 注意: 若插入的表无自增主键则返回 0,异常的话则返回 null
  265. *
  266. * @param sql
  267. * @param para
  268. * @return
  269. * @throws SQLException
  270. * @see [类、类#方法、类#成员]
  271. */
  272. public Long insertSql(String sql, Object[] para)
  273. throws SQLException
  274. {
  275. log.info("InsertSql: {}, para: {}", sql, ToStringBuilder.reflectionToString(para));
  276. Connection conn = null;
  277. Long id = null;
  278. try
  279. {
  280. conn = getConnection();
  281. if (conn != null)
  282. {
  283. // step1: 执行插入操作
  284. PreparedStatement ps = conn.prepareStatement(sql);
  285. if (null != para && para.length > 0)
  286. {
  287. for (int i = 0; i < para.length; i++)
  288. {
  289. ps.setObject(i + 1, para[i]);
  290. }
  291. }
  292. ps.executeUpdate();
  293. // step2: 查询新增记录的自增主键
  294. ps = conn.prepareStatement("SELECT @@IDENTITY");
  295. ResultSet rs = ps.executeQuery();
  296. while (rs.next())
  297. {
  298. id = rs.getLong(1);
  299. }
  300. ps.close();
  301. }
  302. }
  303. catch (Exception e)
  304. {
  305. e.printStackTrace();
  306. log.error("--------- execSql--" + e.getMessage());
  307. }
  308. finally
  309. {
  310. if (conn != null && conn.getAutoCommit() == true)
  311. {
  312. freeConnection();
  313. }
  314. log.info("BaseDAOImpl InsertSql end ");
  315. }
  316. return id;
  317. }
  318. /**
  319. * 带可变参数, 执行sql,返回执行结果
  320. *
  321. * @param sql 执行的sql 语句
  322. * @param para 可变参数
  323. * @return
  324. * @throws SQLException
  325. */
  326. public int execSql(String sql, Object[] para)
  327. throws SQLException
  328. {
  329. log.info("execSql: {}, para: {}", sql, ToStringBuilder.reflectionToString(para));
  330. Connection conn = null;
  331. int rs = 0;
  332. try
  333. {
  334. conn = getConnection();
  335. if (conn != null)
  336. {
  337. PreparedStatement ps = conn.prepareStatement(sql);
  338. if (null != para && para.length > 0)
  339. {
  340. for (int i = 0; i < para.length; i++)
  341. {
  342. ps.setObject(i + 1, para[i]);
  343. }
  344. }
  345. rs = ps.executeUpdate();
  346. ps.close();
  347. }
  348. }
  349. catch (SQLException e)
  350. {
  351. log.error("--------- execSql--" + e.getMessage());
  352. throw e;
  353. }
  354. finally
  355. {
  356. if (conn != null && conn.getAutoCommit() == true)
  357. {
  358. freeConnection();
  359. }
  360. log.info("BaseDAOImpl execSql end ");
  361. }
  362. return rs;
  363. }
  364. /**
  365. * 批量更新
  366. *
  367. * @param sql 需执行的sql
  368. * @param params 二维参数数组
  369. * @throws SQLException
  370. * @see [类、类#方法、类#成员]
  371. */
  372. public void executeBatch(String sql, Object[][] params)
  373. throws SQLException
  374. {
  375. log.info("executeBatch: {}, params:{}", sql, ToStringBuilder.reflectionToString(params));
  376. Connection conn = null;
  377. try
  378. {
  379. conn = getConnection();
  380. if (conn != null)
  381. {
  382. PreparedStatement ps = conn.prepareStatement(sql);
  383. if (null != params && params.length > 0)
  384. {
  385. for (Object[] para : params)
  386. {
  387. for (int i = 0; i < para.length; i++)
  388. {
  389. ps.setObject(i + 1, para[i]);
  390. }
  391. ps.addBatch();
  392. }
  393. }
  394. ps.executeBatch();
  395. ps.close();
  396. }
  397. }
  398. catch (Exception e)
  399. {
  400. log.error("--------- executeBatch Error:" + e.getMessage());
  401. throw new SQLException(e);
  402. }
  403. finally
  404. {
  405. if (conn != null && conn.getAutoCommit() == true)
  406. {
  407. freeConnection();
  408. }
  409. log.info("BaseDAOImpl executeBatch end ");
  410. }
  411. }
  412. /**
  413. * 批量更新
  414. *
  415. * @param sql 需执行的sql
  416. * @param params List参数组
  417. * @throws SQLException
  418. * @see [类、类#方法、类#成员]
  419. */
  420. public void executeBatch(String sql, List<Object[]> params)
  421. throws SQLException
  422. {
  423. log.info("executeBatch: {}, params:{}", sql, ToStringBuilder.reflectionToString(params));
  424. Connection conn = null;
  425. try
  426. {
  427. conn = getConnection();
  428. if (conn != null)
  429. {
  430. PreparedStatement ps = conn.prepareStatement(sql);
  431. if (null != params && params.size() > 0)
  432. {
  433. for (Object[] para : params)
  434. {
  435. for (int i = 0; i < para.length; i++)
  436. {
  437. ps.setObject(i + 1, para[i]);
  438. }
  439. ps.addBatch();
  440. }
  441. }
  442. ps.executeBatch();
  443. ps.close();
  444. }
  445. }
  446. catch (Exception e)
  447. {
  448. log.error("--------- executeBatch Error:" + e.getMessage());
  449. throw new SQLException(e);
  450. }
  451. finally
  452. {
  453. if (conn != null && conn.getAutoCommit() == true)
  454. {
  455. freeConnection();
  456. }
  457. log.info("BaseDAOImpl executeBatch end ");
  458. }
  459. }
  460. /**
  461. * 释放数据库连接
  462. *
  463. * @see [类、类#方法、类#成员]
  464. */
  465. public void freeConnection()
  466. {
  467. log.info("------释放数据库连接-------");
  468. try
  469. {
  470. Connection conn = threadLocal.get();
  471. if (conn != null)
  472. {
  473. conn.close();
  474. threadLocal.remove(); // 解除当前线程上绑定conn
  475. }
  476. }
  477. catch (Exception e)
  478. {
  479. log.error(e.getMessage());
  480. throw new RuntimeException(e);
  481. }
  482. }
  483. // ************** 事务操作 **************
  484. /**
  485. * 开启事务
  486. *
  487. * @param connection
  488. * @throws SQLException
  489. * @see [类、类#方法、类#成员]
  490. */
  491. public void startTransaction()
  492. {
  493. log.info("------开启事务-------");
  494. try
  495. {
  496. Connection conn = threadLocal.get();
  497. if (conn == null)
  498. {
  499. conn = getConnection();
  500. threadLocal.set(conn);
  501. }
  502. conn.setAutoCommit(false); // 开启事务
  503. }
  504. catch (Exception e)
  505. {
  506. log.error(e.getMessage());
  507. }
  508. }
  509. /**
  510. * 提交事务
  511. *
  512. * @see [类、类#方法、类#成员]
  513. */
  514. public void commit()
  515. {
  516. log.info("------提交事务-------");
  517. try
  518. {
  519. Connection conn = threadLocal.get();
  520. if (conn != null)
  521. {
  522. conn.commit();
  523. }
  524. }
  525. catch (Exception e)
  526. {
  527. log.error(e.getMessage());
  528. }
  529. }
  530. /**
  531. * 回滚事务
  532. *
  533. * @see [类、类#方法、类#成员]
  534. */
  535. public void rollback()
  536. {
  537. log.info("------ 系统异常,回滚事务-------");
  538. try
  539. {
  540. Connection conn = threadLocal.get();
  541. if (conn != null)
  542. {
  543. conn.rollback();
  544. }
  545. }
  546. catch (Exception e)
  547. {
  548. log.error(e.getMessage());
  549. }
  550. }
  551. }
复制代码
  1. import java.util.LinkedList;
  2. import java.util.List;
  3. /**
  4. * 分页对象
  5. *
  6. * @author 00fly
  7. * @version [版本号, 2016-3-6]
  8. * @see [相关类/方法]
  9. * @since [产品/模块版本]
  10. */
  11. public class PaginationSupport
  12. {
  13. private long currentPage; // 当前页
  14. private long total; // 总记录数
  15. private int pageSize; // 每页大小
  16. private long totalPage; // 总页数
  17. private long previous; // 上一页
  18. private long next; // 下一页
  19. private List<?> items; // 当前页的数据
  20. @SuppressWarnings("rawtypes")
  21. public PaginationSupport(long total, int pageNo, int pageSize)
  22. {
  23. items = new LinkedList();
  24. this.pageSize = pageSize;
  25. currentPage = pageNo;
  26. setTotal(total);
  27. }
  28. public long getCurrentPage()
  29. {
  30. return currentPage;
  31. }
  32. public void setCurrentPage(int currentPage)
  33. {
  34. this.currentPage = currentPage;
  35. }
  36. public long getTotal()
  37. {
  38. return total;
  39. }
  40. public void setTotal(long totalcount)
  41. {
  42. total = totalcount;
  43. if (totalcount == 0)
  44. {
  45. totalPage = 0;
  46. }
  47. else
  48. {
  49. totalPage = 1 + (totalcount - 1) / pageSize;
  50. }
  51. if (currentPage < 1)
  52. {
  53. currentPage = 1;
  54. }
  55. else if (currentPage > totalPage)
  56. {
  57. currentPage = totalPage;
  58. }
  59. if (1 == currentPage)
  60. {
  61. previous = 1;
  62. }
  63. else
  64. {
  65. previous = currentPage - 1;
  66. }
  67. if (totalPage == currentPage)
  68. {
  69. next = currentPage;
  70. }
  71. else
  72. {
  73. next = currentPage + 1;
  74. }
  75. }
  76. public int getPageSize()
  77. {
  78. return pageSize;
  79. }
  80. public void setPageSize(int pageSize)
  81. {
  82. this.pageSize = pageSize;
  83. }
  84. public long getTotalPage()
  85. {
  86. return totalPage;
  87. }
  88. public void setTotalPage(long totalPage)
  89. {
  90. this.totalPage = totalPage;
  91. }
  92. public long getPrevious()
  93. {
  94. return previous;
  95. }
  96. public void setPrevious(long previous)
  97. {
  98. this.previous = previous;
  99. }
  100. public long getNext()
  101. {
  102. return next;
  103. }
  104. public void setNext(long next)
  105. {
  106. this.next = next;
  107. }
  108. public List<?> getItems()
  109. {
  110. return items;
  111. }
  112. public void setItems(List<?> items)
  113. {
  114. this.items = items;
  115. }
  116. }
复制代码
上一篇:字符串操作2下一篇:url正则匹配

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-5-6 13:01

Copyright 2015-2025 djqfx

返回顶部