最近正在学习泛型DAO,通过网上查阅资料,汇总并自己整理了一下。提前需要学习的知识java反射、泛型
用到的反射如下:
Class<T>类 是java.lang包下,Class类的实例表示正在运行的 Java 应用中的类和接口。
Type接口 是java.lang.reflect包下的是Java类型的通用超级接口。这些包括原始类型,参数化类型,数组类型和类型变量
ParameterizedType接口 是java.lang.reflect包下是Type的子接口,表示一个参数化类型,如Collection<String>
Field类 是java.lang.reflect包下,提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实体字段
AccessibleObject类 是java.lang.reflect包下,是Filed、Method和Constructor对象的基类。提供了将反射的对象标记为在使用时取消默认 Java语言访问控制检查的能力
有人肯定会问什么是参数化类型?
参数化类型就是一个编译器可以自动定制作用于特定类型上的类,个人理解就是泛型
什么是原始类型?
一个原始类型就是一个没有任何类型参数的泛型类或者泛型接口的名字。
eg:List<E> 是一个泛型接口,List<String>是一个参数化的类型,List就是一个原生类型
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
//getGenericSuperclass() 返回此Class 所有的实体(类、接口、基本类型或者void)的直接超类的 Type
Class<T> entityClass = (Class<T>) type.getActualTypeArguments()[0];
//getActualTypeArguments() 返回此类型的实际类型参数的数组Type对象
getDeclaredFields() 返回 Field 对象的一个数组,这些对象所表示的类或接口所声明的所有字段。(公共、保护、默认、私有字段,不包括继承的字段)
newInstance() 创建此 Class 对象的新实例
setAccessible(boolean flag) 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则实施访问检查
下面是泛型DAO的源码
User实体类:
1 package zhr.bean; 2 3 public class User { 4 private int id; 5 private String username; 6 private String password; 7 8 public int getId() { 9 return id; 10 } 11 12 public void setId(int id) { 13 this.id = id; 14 } 15 16 public String getUsername() { 17 return username; 18 } 19 20 public void setUsername(String username) { 21 this.username = username; 22 } 23 24 public String getPassword() { 25 return password; 26 } 27 28 public void setPassword(String password) { 29 this.password = password; 30 } 31 32 @Override 33 public String toString() { 34 return "User [id=" + id + ", username=" + username + ", password=" + password + "]"; 35 } 36 37 }
BaseDao接口:
1 package zhr.dao; 2 3 public interface BaseDao<T> { 4 T selectByID(int id); 5 6 T select(T t); 7 8 void add(T t); 9 10 void update(T t); 11 12 void delete(T t); 13 }
UserDao接口:
1 package zhr.dao; 2 3 import java.util.List; 4 5 import zhr.bean.User; 6 7 public interface UserDao extends BaseDao<User> { 8 List<User> findAll(); 9 }
BaseDaoImpl实现类:
1 package zhr.daoimpl; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.ParameterizedType; 5 import java.sql.Connection; 6 import java.sql.PreparedStatement; 7 import java.sql.ResultSet; 8 import java.sql.SQLException; 9 10 import util.ConnectionManager; 11 import zhr.dao.BaseDao; 12 13 public class BaseDaoImpl<T> implements BaseDao<T> { 14 15 private Connection conn; 16 private PreparedStatement ps; 17 private ResultSet rs; 18 private Class<T> EntityClass;// 获取实体类 19 20 @SuppressWarnings("unchecked") 21 public BaseDaoImpl() { 22 /** 23 * 传递User就是 zhr.daoimpl.BaseDaoImpl<zhr.bean.User> 传递Shop就是 24 * zhr.daoimpl.BaseDaoImpl<zhr.bean.Shop> 25 */ 26 ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass(); 27 System.out.println(type); 28 /** 29 * 这里如果传递的是User.那么就是zhr.bean.User 如果传递的是Shop. 那么就是zhr.bean.Shop 30 * 31 */ 32 33 EntityClass = (Class<T>) type.getActualTypeArguments()[0]; 34 System.out.println(EntityClass); 35 } 36 37 @Override 38 public T selectByID(int id) { 39 StringBuffer sqlb = new StringBuffer(); 40 // 通过反射获取实体类中的所有变量 41 Field fields[] = EntityClass.getDeclaredFields(); 42 sqlb.append("select * from " + EntityClass.getSimpleName() + " where id=?"); 43 T obj = null; 44 try { 45 conn = ConnectionManager.getConnection(); 46 ps = conn.prepareStatement(sqlb.toString()); 47 ps.setInt(1, id); 48 rs = ps.executeQuery(); 49 fields = EntityClass.getDeclaredFields(); 50 while (rs.next()) { 51 obj = EntityClass.newInstance(); 52 for (int i = 0; i < fields.length; i++) { 53 fields[i].setAccessible(true); 54 fields[i].set(obj, rs.getObject(fields[i].getName())); 55 } 56 } 57 58 } catch (SQLException e) { 59 e.printStackTrace(); 60 } catch (InstantiationException e) { 61 e.printStackTrace(); 62 } catch (IllegalAccessException e) { 63 e.printStackTrace(); 64 } 65 return obj; 66 } 67 68 @Override 69 public T select(T t) { 70 StringBuffer sqlb = new StringBuffer(); 71 // 通过反射获取实体类中的所有变量 72 Field fields[] = EntityClass.getDeclaredFields(); 73 sqlb.append("select * from " + EntityClass.getSimpleName() + " where id=?"); 74 T obj = null; 75 try { 76 conn = ConnectionManager.getConnection(); 77 ps = conn.prepareStatement(sqlb.toString()); 78 fields[0].setAccessible(true); 79 ps.setInt(1, (int) fields[0].get(t)); 80 rs = ps.executeQuery(); 81 fields = EntityClass.getDeclaredFields(); 82 while (rs.next()) { 83 obj = EntityClass.newInstance(); 84 for (int i = 0; i < fields.length; i++) { 85 fields[i].setAccessible(true); 86 fields[i].set(obj, rs.getObject(fields[i].getName())); 87 } 88 } 89 90 } catch (SQLException e) { 91 e.printStackTrace(); 92 } catch (InstantiationException e) { 93 e.printStackTrace(); 94 } catch (IllegalAccessException e) { 95 e.printStackTrace(); 96 } 97 return obj; 98 } 99 100 // insert into User(id,username,password) values (?,?,?); 101 @Override 102 public void add(T t) { 103 StringBuffer sql = new StringBuffer(); 104 Field fields[] = EntityClass.getDeclaredFields(); 105 sql.append("insert into " + EntityClass.getSimpleName()); 106 sql.append("("); 107 for (int i = 0; fields != null && i < fields.length; i++) { 108 fields[i].setAccessible(true); // 这句话必须要有,否则会抛出异常. 109 String column = fields[i].getName(); 110 sql.append(column).append(","); 111 } 112 sql = sql.deleteCharAt(sql.length() - 1);// 删除最后一个, 113 sql.append(") values ("); 114 for (int i = 0; fields != null && i < fields.length; i++) { 115 sql.append("?,"); 116 } 117 sql.deleteCharAt(sql.length() - 1);// 删除最后一个, 118 sql.append(")"); 119 try { 120 conn = ConnectionManager.getConnection(); 121 ps = conn.prepareStatement(sql.toString()); 122 Object obj[] = new Object[fields.length]; 123 for (int i = 0; obj != null && i < fields.length; i++) { 124 fields[i].setAccessible(true);// AccessibleTest类中的成员变量为private,故必须进行此操 125 obj[i] = fields[i].get(t); 126 } 127 128 for (int i = 0; i < obj.length; i++) { 129 ps.setObject(i + 1, obj[i]); 130 } 131 ps.executeUpdate(); 132 System.out.println("添加成功"); 133 134 } catch (SQLException e) { 135 e.printStackTrace(); 136 } catch (IllegalArgumentException e) { 137 e.printStackTrace(); 138 } catch (IllegalAccessException e) { 139 e.printStackTrace(); 140 } finally { 141 try { 142 ps.close(); 143 } catch (SQLException e) { 144 e.printStackTrace(); 145 } 146 try { 147 conn.close(); 148 } catch (SQLException e) { 149 e.printStackTrace(); 150 } 151 } 152 153 } 154 155 // update User set username=?,password=? where id=? 156 @Override 157 public void update(T t) { 158 StringBuffer sql = new StringBuffer(); 159 Field fields[] = EntityClass.getDeclaredFields(); 160 sql.append("update " + EntityClass.getSimpleName() + " set "); 161 for (int i = 0; fields != null && i < fields.length; i++) { 162 fields[i].setAccessible(true); 163 String column = fields[i].getName(); 164 if (column.equals("id")) { 165 continue; 166 } 167 sql.append(column).append("=").append("?,"); 168 } 169 sql.deleteCharAt(sql.length() - 1); 170 sql.append(" where id=?"); 171 172 try { 173 conn = ConnectionManager.getConnection(); 174 ps = conn.prepareStatement(sql.toString()); 175 176 Object Tempobj[] = new Object[fields.length]; 177 for (int i = 0; Tempobj != null && i < fields.length; i++) { 178 fields[i].setAccessible(true); 179 Tempobj[i] = fields[i].get(t); 180 } 181 Object obj[] = new Object[fields.length]; 182 System.arraycopy(Tempobj, 1, obj, 0, Tempobj.length - 1); 183 obj[obj.length - 1] = Tempobj[0]; 184 185 for (int i = 0; i < obj.length; i++) { 186 ps.setObject(i + 1, obj[i]); 187 } 188 189 ps.executeUpdate(); 190 System.out.println("更新成功"); 191 192 } catch (SQLException e) { 193 e.printStackTrace(); 194 } catch (IllegalArgumentException e) { 195 e.printStackTrace(); 196 } catch (IllegalAccessException e) { 197 e.printStackTrace(); 198 } finally { 199 try { 200 ps.close(); 201 } catch (SQLException e) { 202 e.printStackTrace(); 203 } 204 try { 205 conn.close(); 206 } catch (SQLException e) { 207 e.printStackTrace(); 208 } 209 } 210 211 } 212 213 @Override 214 public void delete(T t) { 215 StringBuffer sql = new StringBuffer(); 216 Field fields[] = EntityClass.getDeclaredFields(); 217 218 sql.append("delete from " + EntityClass.getSimpleName() + " where id=?"); 219 220 try { 221 conn = ConnectionManager.getConnection(); 222 ps = conn.prepareStatement(sql.toString()); 223 224 Object obj[] = new Object[1]; 225 fields[0].setAccessible(true); 226 obj[0] = fields[0].get(t); 227 228 for (int i = 0; i < obj.length; i++) {// 设置参数 229 ps.setObject(i + 1, obj[i]); 230 } 231 232 ps.executeUpdate(); 233 System.out.println("删除成功"); 234 235 } catch (SQLException e) { 236 e.printStackTrace(); 237 } catch (IllegalArgumentException e) { 238 e.printStackTrace(); 239 } catch (IllegalAccessException e) { 240 e.printStackTrace(); 241 } finally { 242 try { 243 ps.close(); 244 } catch (SQLException e) { 245 e.printStackTrace(); 246 } 247 try { 248 conn.close(); 249 } catch (SQLException e) { 250 e.printStackTrace(); 251 } 252 } 253 254 } 255 256 }
UserDaoImpl实现类:
1 package zhr.daoimpl; 2 3 import java.lang.reflect.ParameterizedType; 4 import java.sql.Connection; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.util.ArrayList; 8 import java.util.List; 9 10 import util.ConnectionManager; 11 import zhr.bean.User; 12 import zhr.dao.UserDao; 13 14 public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao { 15 16 private Connection conn; 17 private PreparedStatement ps; 18 private ResultSet rs; 19 private Class<User> EntityClass;// 获取实体类 20 private List<User> list; 21 private String sql; 22 23 public UserDaoImpl() { 24 /** 25 * 传递User就是 com.example.daoimp.BaseDaoImpl<com.example.bean.User> 传递Shop就是 26 * com.example.daoimp.BaseDaoImpl<com.example.bean.Shop> 27 */ 28 ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass(); 29 /** 30 * 这里如果传递的是User.那么就是class com.example.bean.User 如果传递的是Shop. 那么就是class 31 * com.example.bean.Shop 32 */ 33 34 EntityClass = (Class<User>) type.getActualTypeArguments()[0]; 35 } 36 37 @Override 38 public List<User> findAll() { 39 StringBuffer b = new StringBuffer(); 40 list = new ArrayList<User>(); 41 sql = b.append("select * from " + EntityClass.getSimpleName()).toString(); 42 try { 43 conn = ConnectionManager.getConnection(); 44 ps = conn.prepareStatement(sql); 45 rs = ps.executeQuery(); 46 while (rs.next()) { 47 User user = new User(); 48 user.setId(rs.getInt("id")); 49 user.setUsername(rs.getString("username")); 50 user.setPassword(rs.getString("password")); 51 list.add(user); 52 } 53 } catch (Exception e) { 54 e.printStackTrace(); 55 } 56 return list; 57 } 58 59 }
ConnectionManager工具类:
1 package util; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.SQLException; 6 7 public class ConnectionManager { 8 public static Connection getConnection() { 9 Connection conn = null; 10 String url = "jdbc:mysql://localhost:3306/test"; 11 String username = "root"; 12 String password = "root"; 13 try { 14 Class.forName("com.mysql.jdbc.Driver"); 15 conn = DriverManager.getConnection(url, username, password); 16 } catch (ClassNotFoundException e) { 17 e.printStackTrace(); 18 System.out.println("没有找到文件"); 19 } catch (SQLException e) { 20 e.printStackTrace(); 21 System.out.println("sql异常"); 22 } 23 return conn; 24 } 25 }
测试类:
ackage zhr.test; import java.util.List; import zhr.bean.User; import zhr.dao.UserDao; import zhr.daoimpl.UserDaoImpl; public class Test { public static void main(String[] args) { List<User> list = null; UserDaoImpl imp = new UserDaoImpl(); list = imp.findAll(); for (User user : list) { System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword()); } // 查询 User ua = (User) imp.selectByID(1);// 通过id查询User System.out.println(ua.getClass().getSimpleName()); System.out.println(ua); System.out.println(ua.getId() + " " + ua.getUsername() + " " + ua.getPassword()); /* * 添加操作 User user = new User(); user.setId(11); user.setUsername("zhr"); * user.setPassword("123456"); imp.add(user); */ /* * 更新操作 User user1 = new User(); user1.setId(1); user1.setUsername("hhh"); * user1.setPassword("123"); imp.update(user1); */ /* * 删除操作 User user2 = new User(); user2.setId(11); user2.setUsername("zhr"); * user2.setPassword("123456"); imp.delete(user2); */ } }
时隔一年,再次写博客,希望大家互相支持,相互学习,有不对的地方可以评论留言。记得粉我噢~谢谢大家。