⾸先解释⼀下为什么要学习泛型DAO。平时在写DAO的时候是⼀个接⼝对应⼀个实现类,实现类⾥⾯要写很多的操作数据库的⽅法。当我们有很多的javaben的时候我们会写很多的接⼝和实现类,并且⾥⾯的代码都是相同的,这样太⿇烦,我们就不能写⼀个类,在类⾥⾯传⼊泛型,让类根据泛型,创建出⼀个实例对象,这样就出现了泛型DAO。
⼀、需要提前准备的知识如下
反射关键的类:
Class Type接⼝ 是java.lang.reflect包下的是Java类型的通⽤超级接⼝。这些包括原始类型,参数化类型,数组类型和类型变量ParameterizedType接⼝ 是java.lang.reflect包下是Type的⼦接⼝,表⽰⼀个参数化类型,如Collection Field类 是java.lang.reflect包下,提供有关类或接⼝的单个字段的信息,以及对它的动态访问权限。反射的字段可能是⼀个类(静态)字段或 实体字段 AccessibleObject类 是java.lang.reflect包下,是Filed、Method和Constructor对象的基类。提供了将反射的对象标记为在使⽤时取消默认 Java 语⾔访问控制检查的能⼒ 反射关键的⽅法: ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass(); //getGenericSuperclass() 返回此Class 所有的实体(类、接⼝、基本类型或者void)的直接超类的 TypeClass getDeclaredFields() 返回 Field 对象的⼀个数组,这些对象所表⽰的类或接⼝所声明的所有字段。(公共、保护、默认、私有字段,不包括继承的字段) newInstance() 创建此 Class 对象的新实例 setAccessible(boolean flag) 值为 true 则指⽰反射的对象在使⽤时应该取消 Java 语⾔访问检查。值为 false 则实施访问检查 ⼆、下⾯是泛型DAO的源码 User实体类:主要声明⼀个实体,get、set⽅法来获取实体的属性 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 + \35 }36 37 } BaseDao接⼝:⽤来写泛型DAO的核⼼接⼝主要就是⼀些增删改查的⽅法 1 package zhr.dao; 2 3 public interface BaseDao 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接⼝:主要DAO接⼝,类似的DAO接⼝也可以写这样只需要继承BaseDao接⼝就可以,提⾼了代码的复⽤性,也可以⾃⼰定义功能⽅法 1 package zhr.dao;2 3 import java.util.List;4 5 import zhr.bean.User;6 7 public interface UserDao extends BaseDao BaseDaoImpl实现类:实现BaseDao接⼝,构造⽅法使⽤了反射获取实体类,这是泛型DAO核⼼实现类,需要详细写,增删改查,或者更多功能,⽐如通过id来查询,或者给两个参数查询between and,⼤于或者⼩于 核⼼思想就是反射。 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 15 private Connection conn; 16 private PreparedStatement ps; 17 private ResultSet rs; 18 private Class 20 @SuppressWarnings(\"unchecked\") 21 public BaseDaoImpl() { 22 /** 23 * 传递User就是 zhr.daoimpl.BaseDaoImpl 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 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); 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(); } 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 } 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 }1 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();1 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 1 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 2 }255 256 } BaseDaoImpl实现类 UserDaoImpl实现类:这是⽤户的实现类,继承了BaseDaoImpl并且实现 UserDao 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 16 private Connection conn; 17 private PreparedStatement ps;18 private ResultSet rs; 19 private Class 23 public UserDaoImpl() {24 /** 25 * 传递User就是 com.example.daoimp.BaseDaoImpl 28 ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();29 /** 30 * 这⾥如果传递的是User.那么就是class com.example.bean.User 如果传递的是Shop. 那么就是class31 * com.example.bean.Shop 32 */33 34 EntityClass = (Class 37 @Override 38 public List 39 StringBuffer b = new StringBuffer();40 list = new ArrayList 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) { e.printStackTrace();55 } 56 return list;57 }58 59 } ConnectionManager⼯具类:主要⽤来获取连接Connection 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 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); */ }} 时隔⼀年,再次写博客,希望⼤家互相⽀持,相互学习,有不对的地⽅可以评论留⾔。记得粉我噢~谢谢⼤家。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- efsc.cn 版权所有 赣ICP备2024042792号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务