微信登录

JDBC - 抽象类 - BaseDAO.java

一共提供4个方法

1个增删改
3个查 - 返回一条记录
3个查 - 返回多条记录
3个查 - 返回特殊值(date、Long等)

  1. package com.atguigu3.dao;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.ParameterizedType;
  4. import java.lang.reflect.Type;
  5. import java.sql.Connection;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.ResultSetMetaData;
  9. import java.sql.SQLException;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import com.atguigu1.util.JDBCUtils;
  13. /*
  14. * DAO: data(base) access object
  15. * 封装了针对于数据表的通用的操作
  16. */
  17. public abstract class BaseDAO<T> {
  18. private Class<T> clazz = null;
  19. // public BaseDAO(){
  20. //
  21. // }
  22. {
  23. //获取当前BaseDAO的子类继承的父类中的泛型
  24. Type genericSuperclass = this.getClass().getGenericSuperclass();
  25. ParameterizedType paramType = (ParameterizedType) genericSuperclass;
  26. Type[] typeArguments = paramType.getActualTypeArguments();//获取了父类的泛型参数
  27. clazz = (Class<T>) typeArguments[0];//泛型的第一个参数
  28. }
  29. // 通用的增删改操作---version 2.0 (考虑上事务)
  30. public int update(Connection conn, String sql, Object... args) {// sql中占位符的个数与可变形参的长度相同!
  31. PreparedStatement ps = null;
  32. try {
  33. // 1.预编译sql语句,返回PreparedStatement的实例
  34. ps = conn.prepareStatement(sql);
  35. // 2.填充占位符
  36. for (int i = 0; i < args.length; i++) {
  37. ps.setObject(i + 1, args[i]);// 小心参数声明错误!!
  38. }
  39. // 3.执行
  40. return ps.executeUpdate();
  41. } catch (Exception e) {
  42. e.printStackTrace();
  43. } finally {
  44. // 4.资源的关闭
  45. JDBCUtils.closeResource(null, ps);
  46. }
  47. return 0;
  48. }
  49. // 通用的查询操作,用于返回数据表中的一条记录(version 2.0:考虑上事务)
  50. public T getInstance(Connection conn, String sql, Object... args) {
  51. PreparedStatement ps = null;
  52. ResultSet rs = null;
  53. try {
  54. ps = conn.prepareStatement(sql);
  55. for (int i = 0; i < args.length; i++) {
  56. ps.setObject(i + 1, args[i]);
  57. }
  58. rs = ps.executeQuery();
  59. // 获取结果集的元数据 :ResultSetMetaData
  60. ResultSetMetaData rsmd = rs.getMetaData();
  61. // 通过ResultSetMetaData获取结果集中的列数
  62. int columnCount = rsmd.getColumnCount();
  63. if (rs.next()) {
  64. T t = clazz.newInstance();
  65. // 处理结果集一行数据中的每一个列
  66. for (int i = 0; i < columnCount; i++) {
  67. // 获取列值
  68. Object columValue = rs.getObject(i + 1);
  69. // 获取每个列的列名
  70. // String columnName = rsmd.getColumnName(i + 1);
  71. String columnLabel = rsmd.getColumnLabel(i + 1);
  72. // 给t对象指定的columnName属性,赋值为columValue:通过反射
  73. Field field = clazz.getDeclaredField(columnLabel);
  74. field.setAccessible(true);
  75. field.set(t, columValue);
  76. }
  77. return t;
  78. }
  79. } catch (Exception e) {
  80. e.printStackTrace();
  81. } finally {
  82. JDBCUtils.closeResource(null, ps, rs);
  83. }
  84. return null;
  85. }
  86. // 通用的查询操作,用于返回数据表中的多条记录构成的集合(version 2.0:考虑上事务)
  87. public List<T> getForList(Connection conn, String sql, Object... args) {
  88. PreparedStatement ps = null;
  89. ResultSet rs = null;
  90. try {
  91. ps = conn.prepareStatement(sql);
  92. for (int i = 0; i < args.length; i++) {
  93. ps.setObject(i + 1, args[i]);
  94. }
  95. rs = ps.executeQuery();
  96. // 获取结果集的元数据 :ResultSetMetaData
  97. ResultSetMetaData rsmd = rs.getMetaData();
  98. // 通过ResultSetMetaData获取结果集中的列数
  99. int columnCount = rsmd.getColumnCount();
  100. // 创建集合对象
  101. ArrayList<T> list = new ArrayList<T>();
  102. while (rs.next()) {
  103. T t = clazz.newInstance();
  104. // 处理结果集一行数据中的每一个列:给t对象指定的属性赋值
  105. for (int i = 0; i < columnCount; i++) {
  106. // 获取列值
  107. Object columValue = rs.getObject(i + 1);
  108. // 获取每个列的列名
  109. // String columnName = rsmd.getColumnName(i + 1);
  110. String columnLabel = rsmd.getColumnLabel(i + 1);
  111. // 给t对象指定的columnName属性,赋值为columValue:通过反射
  112. Field field = clazz.getDeclaredField(columnLabel);
  113. field.setAccessible(true);
  114. field.set(t, columValue);
  115. }
  116. list.add(t);
  117. }
  118. return list;
  119. } catch (Exception e) {
  120. e.printStackTrace();
  121. } finally {
  122. JDBCUtils.closeResource(null, ps, rs);
  123. }
  124. return null;
  125. }
  126. //用于查询特殊值的通用的方法
  127. public <E> E getValue(Connection conn,String sql,Object...args){
  128. PreparedStatement ps = null;
  129. ResultSet rs = null;
  130. try {
  131. ps = conn.prepareStatement(sql);
  132. for(int i = 0;i < args.length;i++){
  133. ps.setObject(i + 1, args[i]);
  134. }
  135. rs = ps.executeQuery();
  136. if(rs.next()){
  137. return (E) rs.getObject(1);
  138. }
  139. } catch (SQLException e) {
  140. e.printStackTrace();
  141. }finally{
  142. JDBCUtils.closeResource(null, ps, rs);
  143. }
  144. return null;
  145. }
  146. }