JDBC实现用于操作数据库Mysql的工具类JDBCTools和DAO--完整可用版

本文介绍了一套基于JDBC操作Mysql数据库的工具类JDBCTools和DAO,包括连接数据库、关闭资源、执行SQL语句等通用方法,并实现了泛型、反射、集合等技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDBC实现用于操作数据库Mysql的工具类JDBCTools和DAO--完整可用版

    前面的博文,写了一篇关于一套采用JDBC操作Mysql数据库的JDBCTools工具类,觉得不够完美,学习了尚硅谷的视频后,觉得其很是牛逼,写的DAO具有通用的模式,其中DAO是:Database Access Object 数据库访问对象

    在DAO中,我们只是完成与数据库中的数据进行交互的业务逻辑,而控制逻辑我们不会在这里实现。主要包括:update更新方法:包括insert,delete,update。get()是用于获取结果集中只有一条记录的方法。getForList()是用于获取结果集中有多条记录的方法。而getForValue()用于获取结果集中只有一列的方法(比如想要获取数据库表中的某一列,COUNT(*),MAX(columnName)等)

    下面是JDBCTools类


 
  1. import java.io.InputStream;

  2. import java.sql.Connection;

  3. import java.sql.DriverManager;

  4. import java.sql.ResultSet;

  5. import java.sql.SQLException;

  6. import java.sql.Statement;

  7. import java.util.Properties;

  8.  
  9. /**

  10. * JDBC 的工具类

  11. *

  12. * 其中包含: 获取数据库连接, 关闭数据库资源等方法.

  13. */

  14. public class JDBCTools {

  15.  
  16. public static Connection getConnection() throws Exception {

  17. Properties properties = new Properties();

  18. InputStream inStream = JDBCTools.class.getClassLoader()

  19. .getResourceAsStream("jdbc.properties");

  20. properties.load(inStream);

  21.  
  22. // 1. 准备获取连接的 4 个字符串: user, password, url, jdbcDriver

  23. String user = properties.getProperty("user");

  24. String password = properties.getProperty("password");

  25. String url= properties.getProperty("url");

  26. String jdbcDriver= properties.getProperty("jdbcDriver");

  27.  
  28. // 2. 加载驱动: Class.forName(driverClass)

  29. Class.forName(jdbcDriver);

  30.  
  31. // 3.获取数据库连接

  32. Connection connection = DriverManager.getConnection(url, user,

  33. password);

  34. return connection;

  35. }

  36.  
  37. public static void releaseDB(ResultSet resultSet, Statement statement,

  38. Connection connection) {

  39.  
  40. if (resultSet != null) {

  41. try {

  42. resultSet.close();

  43. } catch (SQLException e) {

  44. e.printStackTrace();

  45. }

  46. }

  47.  
  48. if (statement != null) {

  49. try {

  50. statement.close();

  51. } catch (SQLException e) {

  52. e.printStackTrace();

  53. }

  54. }

  55.  
  56. if (connection != null) {

  57. try {

  58. connection.close();

  59. } catch (SQLException e) {

  60. e.printStackTrace();

  61. }

  62. }

  63. }

  64.  
  65. }


     其中属性配置文件jdbc.properties需要放在项目的src目录下

 

 


 
  1. jdbcDriver=com.mysql.jdbc.Driver

  2. url=jdbc:mysql://localhost:3306/test

  3. user=root

  4. password=root


    接着是DAO工具类

 

 


 
  1. import java.lang.reflect.Field;

  2. import java.lang.reflect.InvocationTargetException;

  3. import java.sql.Connection;

  4. import java.sql.PreparedStatement;

  5. import java.sql.ResultSet;

  6. import java.sql.ResultSetMetaData;

  7. import java.sql.SQLException;

  8. import java.util.ArrayList;

  9. import java.util.HashMap;

  10. import java.util.List;

  11. import java.util.Map;

  12.  
  13. public class DAO {

  14.  
  15. // INSERT, UPDATE, DELETE 操作都可以包含在其中

  16. public void update(String sql, Object... args) {

  17. Connection connection = null;

  18. PreparedStatement preparedStatement = null;

  19.  
  20. try {

  21. connection = JDBCTools.getConnection();

  22. preparedStatement = connection.prepareStatement(sql);

  23.  
  24. for (int i = 0; i < args.length; i++) {

  25. preparedStatement.setObject(i + 1, args[i]);

  26. }

  27.  
  28. preparedStatement.executeUpdate();

  29. } catch (Exception e) {

  30. e.printStackTrace();

  31. } finally {

  32. JDBCTools.releaseDB(null, preparedStatement, connection);

  33. }

  34. }

  35.  
  36. // 查询一条记录, 返回对应的对象

  37. public <T> T get(Class<T> clazz, String sql, Object... args) {

  38. List<T> result = getForList(clazz, sql, args);

  39. if(result.size() > 0){

  40. return result.get(0);

  41. }

  42.  
  43. return null;

  44. }

  45.  
  46. /**

  47. * 传入 SQL 语句和 Class 对象, 返回 SQL 语句查询到的记录对应的 Class 类的对象的集合

  48. * @param clazz: 对象的类型

  49. * @param sql: SQL 语句

  50. * @param args: 填充 SQL 语句的占位符的可变参数.

  51. * @return

  52. */

  53. public <T> List<T> getForList(Class<T> clazz,

  54. String sql, Object... args) {

  55.  
  56. List<T> list = new ArrayList<>();

  57.  
  58. Connection connection = null;

  59. PreparedStatement preparedStatement = null;

  60. ResultSet resultSet = null;

  61.  
  62. try {

  63. //1. 得到结果集

  64. connection = JDBCTools.getConnection();

  65. preparedStatement = connection.prepareStatement(sql);

  66.  
  67. for (int i = 0; i < args.length; i++) {

  68. preparedStatement.setObject(i + 1, args[i]);

  69. }

  70.  
  71. resultSet = preparedStatement.executeQuery();

  72.  
  73. //2. 处理结果集, 得到 Map 的 List, 其中一个 Map 对象

  74. //就是一条记录. Map 的 key 为 reusltSet 中列的别名, Map 的 value

  75. //为列的值.

  76. List<Map<String, Object>> values =

  77. handleResultSetToMapList(resultSet);

  78.  
  79. //3. 把 Map 的 List 转为 clazz 对应的 List

  80. //其中 Map 的 key 即为 clazz 对应的对象的 propertyName,

  81. //而 Map 的 value 即为 clazz 对应的对象的 propertyValue

  82. list = transfterMapListToBeanList(clazz, values);

  83.  
  84. } catch (Exception e) {

  85. e.printStackTrace();

  86. } finally {

  87. JDBCTools.releaseDB(resultSet, preparedStatement, connection);

  88. }

  89.  
  90. return list;

  91. }

  92.  
  93. /**

  94. * 转换List<Map> 为 List<T>

  95. * @param clazz

  96. * @param values

  97. * @return

  98. * @throws InstantiationException

  99. * @throws IllegalAccessException

  100. * @throws InvocationTargetException

  101. */

  102. public <T> List<T> transfterMapListToBeanList(Class<T> clazz,

  103. List<Map<String, Object>> values) throws Exception {

  104.  
  105. List<T> result = new ArrayList<>();

  106.  
  107. T bean = null;

  108.  
  109. if (values.size() > 0) {

  110. for (Map<String, Object> m : values) {

  111. //通过反射创建一个其他类的对象

  112. bean = clazz.newInstance();

  113.  
  114. for (Map.Entry<String, Object> entry : m.entrySet()) {

  115. String propertyName = entry.getKey();

  116. Object value = entry.getValue();

  117.  
  118. Field f=bean.getClass().getDeclaredField(propertyName);

  119. f.setAccessible(true);

  120. f.set(bean, value);

  121.  
  122. //BeanUtils.setProperty(bean, propertyName, value);

  123. }

  124. // 13. 把 Object 对象放入到 list 中.

  125. result.add(bean);

  126. }

  127. }

  128.  
  129. return result;

  130. }

  131.  
  132. /**

  133. * 处理结果集, 得到 Map 的一个 List, 其中一个 Map 对象对应一条记录

  134. *

  135. * @param resultSet

  136. * @return

  137. * @throws SQLException

  138. */

  139. public List<Map<String, Object>> handleResultSetToMapList(

  140. ResultSet resultSet) throws SQLException {

  141. // 5. 准备一个 List<Map<String, Object>>:

  142. // 键: 存放列的别名, 值: 存放列的值. 其中一个 Map 对象对应着一条记录

  143. List<Map<String, Object>> values = new ArrayList<>();

  144.  
  145. List<String> columnLabels = getColumnLabels(resultSet);

  146. Map<String, Object> map = null;

  147.  
  148. // 7. 处理 ResultSet, 使用 while 循环

  149. while (resultSet.next()) {

  150. map = new HashMap<>();

  151.  
  152. for (String columnLabel : columnLabels) {

  153. Object value = resultSet.getObject(columnLabel);

  154. map.put(columnLabel, value);

  155. }

  156.  
  157. // 11. 把一条记录的一个 Map 对象放入 5 准备的 List 中

  158. values.add(map);

  159. }

  160. return values;

  161. }

  162.  
  163. /**

  164. * 获取结果集的 ColumnLabel 对应的 List

  165. *

  166. * @param rs

  167. * @return

  168. * @throws SQLException

  169. */

  170. private List<String> getColumnLabels(ResultSet rs) throws SQLException {

  171. List<String> labels = new ArrayList<>();

  172.  
  173. ResultSetMetaData rsmd = rs.getMetaData();

  174. for (int i = 0; i < rsmd.getColumnCount(); i++) {

  175. labels.add(rsmd.getColumnLabel(i + 1));

  176. }

  177.  
  178. return labels;

  179. }

  180.  
  181. // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.)

  182. public <E> E getForValue(String sql, Object... args) {

  183.  
  184. //1. 得到结果集: 该结果集应该只有一行, 且只有一列

  185. Connection connection = null;

  186. PreparedStatement preparedStatement = null;

  187. ResultSet resultSet = null;

  188.  
  189. try {

  190. //1. 得到结果集

  191. connection = JDBCTools.getConnection();

  192. preparedStatement = connection.prepareStatement(sql);

  193.  
  194. for (int i = 0; i < args.length; i++) {

  195. preparedStatement.setObject(i + 1, args[i]);

  196. }

  197.  
  198. resultSet = preparedStatement.executeQuery();

  199.  
  200. if(resultSet.next()){

  201. return (E) resultSet.getObject(1);

  202. }

  203. } catch(Exception ex){

  204. ex.printStackTrace();

  205. } finally{

  206. JDBCTools.releaseDB(resultSet, preparedStatement, connection);

  207. }

  208. //2. 取得结果

  209. return null;

  210. }

  211. }

     上面的代码我个人做了一些修改,目前是可以通用的。觉得写出这样的代码真是给力,牛逼,秉承着代码精简,模块可重用以及可维护和功能全面的原则进行编程真是自己应该贯彻的!

    上面用到了:泛型(特别是泛型方法),反射机制(特别是如果通过反射定义一个其他类的对象newInstance(),通过反射修改其他类的属性的值),可变形参的使用,以及集合中的List,ArrayList,Map,HashMap。这些知识点跟JDBC的整合,我觉得很是经典,巧妙

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值