基于ejb3,对JDBC进行封装,让使用JDBC时能像hibernate使用annotation注解一样简便,而且更加轻巧
为了方便阅读,必须对Java的泛型和反射有一定的了解,以及hibernate的annotation注解使用有一定的了解,因为这个封装就是对hibernate的部分功能的模仿,虽然性能不像hibernate那样齐全,但至少能让JDBC的使用变得十分简便,而且让项目跑起来变得十分轻巧,开发变得更加的简便,少去的市面上部分半自动的ORM框架还要配置文件的烦恼
ejb3的sun后期根据市面上多种多样的框架的出现后提供的一个标准导致后来许多的框架都是基于这个标准更新和编写的,像我们常用的三大框架,所以我们现在也基于ejb3提供的注解,对JDBC进行简单的封装,下面就是对封装的步骤的说明和使用的演示
首先模仿hibernate通过annotation注解让实体类和数据库的表和字段进行映射:
这是一个User的实体类代码,通过@Table 注解让其对数据库的一张名字为TEST_USER形成映射,@Id 注解表明此成员变量与TEST_USER的主键形成映,@Column 注解表明此成员变量与TEST_USER表对应哪个字段
1 package com.po; 2 3 import java.util.Date; 4 import java.util.List; 5 6 import javax.persistence.Column; 7 import javax.persistence.Id; 8 import javax.persistence.JoinColumn; 9 import javax.persistence.JoinTable; 10 import javax.persistence.ManyToMany; 11 import javax.persistence.OneToMany; 12 import javax.persistence.OneToOne; 13 import javax.persistence.Table; 14 15 16 /** 17 * @author LinBingcheng<494410479@qq.com> 18 * @date 2014年7月31日 19 * @CopyRight 2014 Topview Inc 20 * @version v1.0 21 */ 22 @Table(name = "TEST_USER") 23 public class User { 24 25 private String id; 26 private String name; 27 private Date date; 28 private Info info; 29 private List<Book> books; 30 private List<Role> roles; 31 32 @Id 33 @Column(name = "ID") 34 public String getId() { 35 return id; 36 } 37 38 public void setId(String id) { 39 this.id = id; 40 } 41 42 @Column(name = "USERNAME") 43 public String getName() { 44 return name; 45 } 46 47 public void setName(String name) { 48 this.name = name; 49 } 50 51 @Column(name = "DATE") 52 public Date getDate() { 53 return date; 54 } 55 56 public void setDate(Date date) { 57 this.date = date; 58 } 59 60 @OneToOne(targetEntity = Info.class, mappedBy = "USER_ID") 61 // 关联的表的实体类,主键所对应的外键的名字 62 public Info getInfo() { 63 return info; 64 } 65 66 public void setInfo(Info info) { 67 this.info = info; 68 } 69 70 @OneToMany(targetEntity = Book.class, mappedBy = "USER_ID") 71 //关联的表的实体类,主键所对应的外键的名字 72 public List<Book> getBooks() { 73 return books; 74 } 75 76 public void setBooks(List<Book> books) { 77 this.books = books; 78 } 79 80 @ManyToMany(targetEntity=Role.class) 81 @JoinTable(name="USER_ROLE", 82 joinColumns={@JoinColumn(name="USER_ID")}, 83 inverseJoinColumns={@JoinColumn(name="ROLE_ID")}) 84 public List<Role> getRoles() { 85 return roles; 86 } 87 88 public void setRoles(List<Role> roles) { 89 this.roles = roles; 90 } 91 92 @Override 93 public String toString() { 94 return "User [id=" + id + ", name=" + name + ", date=" + date 95 + ", info=" + info + ", books=" + books + ", roles=" + roles 96 + "]"; 97 } 98 99 100 }
这是一个Info的实体类,通过上面可以看出他与数据库的TEST_INFO表形成映射了,在这里有@OneToOne 注解,这个说明了这张表与数据库的另外一张表形成一对一的关联关系,同样在上面的Uer表也存在一个@OneToOne 注解,而且这两个注解的 targetEntity 属性是相互对应的,说明这两张表两两关联,形成一对一的关联关系,mappedBy属性著名相互关联的外键,标有@JoinColumn 注解的是副表 没有这个@JoinColumn注解的是主表,@JoinColumn里面是副表关联主表的字段
1 package com.po; 2 3 import javax.persistence.Column; 4 import javax.persistence.Id; 5 import javax.persistence.JoinColumn; 6 import javax.persistence.OneToOne; 7 import javax.persistence.Table; 8 9 @Table(name = "TEST_INFO") 10 public class Info { 11 12 private String id; 13 private String info; 14 private User user; 15 16 @Id 17 @Column(name = "ID") 18 public String getId() { 19 return id; 20 } 21 22 public void setId(String id) { 23 this.id = id; 24 } 25 26 @Column(name = "INFO") 27 public String getInfo() { 28 return info; 29 } 30 31 public void setInfo(String info) { 32 this.info = info; 33 } 34 35 @OneToOne(targetEntity = User.class, mappedBy = "ID")//外键的表和外键在另外一张表的字段 36 @JoinColumn(name = "USER_ID") 37 public User getUser() { 38 return user; 39 } 40 41 public void setUser(User user) { 42 this.user = user; 43 } 44 45 @Override 46 public String toString() { 47 return "Info [id=" + id + ", info=" + info + ", user=" + user + "]"; 48 } 49 50 51 }
这个类里面有个@ManyToOne 的注解,与这个对应的是User表里面的@OneToMany的注解,标志这个注解,说明这两张表是多对一关联的,这两个注解的 targetEntity 属性也是是相互对应的
1 package com.po; 2 3 import javax.persistence.Column; 4 import javax.persistence.Id; 5 import javax.persistence.JoinColumn; 6 import javax.persistence.ManyToOne; 7 import javax.persistence.Table; 8 9 @Table(name = "TEST_BOOK") 10 public class Book { 11 12 private String id; 13 private String bookName; 14 private User user; 15 16 @Id 17 @Column(name = "ID") 18 public String getId() { 19 return id; 20 } 21 22 public void setId(String id) { 23 this.id = id; 24 } 25 26 @Column(name = "BOOK_NAME") 27 public String getBookName() { 28 return bookName; 29 } 30 31 public void setBookName(String bookName) { 32 this.bookName = bookName; 33 } 34 35 @ManyToOne(targetEntity=User.class)//关联的表的名字 36 @JoinColumn(name="USER_ID") 37 public User getUser() { 38 return user; 39 } 40 41 public void setUser(User user) { 42 this.user = user; 43 } 44 45 @Override 46 public String toString() { 47 return "Book [id=" + id + ", bookName=" + bookName + ", user=" + user 48 + "]"; 49 } 50 51 52 53 }
这个实体类里面有个@ManyToMany 的注解,对应的User实体类也有,targetEntity 属性是相互对应的,表明这两张表相互之间是多对多是关系,@JoinTable 注解是中间表解释,利用这个注解内部可以实现多对多关联查询,name 属性是中间关联表的名字,joinColumns 是此表在关联表中对应的字段 inverseJoinColumns 是关联的另一张表对应在中间表的字段
1 package com.po; 2 3 import java.util.List; 4 5 import javax.persistence.Column; 6 import javax.persistence.Id; 7 import javax.persistence.JoinColumn; 8 import javax.persistence.JoinTable; 9 import javax.persistence.ManyToMany; 10 import javax.persistence.Table; 11 12 @Table(name="TEST_ROLE") 13 public class Role { 14 15 private int id; 16 private String role; 17 private List<User> users; 18 19 public Role() { 20 } 21 22 public Role(int id,String role) { 23 this.id = id; 24 this.role = role; 25 } 26 27 @Id 28 @Column(name="ID") 29 public int getId() { 30 return id; 31 } 32 33 public void setId(int id) { 34 this.id = id; 35 } 36 37 @Column(name="ROLE") 38 public String getRole() { 39 return role; 40 } 41 42 public void setRole(String role) { 43 this.role = role; 44 } 45 46 @ManyToMany(targetEntity=User.class) 47 @JoinTable(name="USER_ROLE", 48 joinColumns={@JoinColumn(name="ROLE_ID")}, 49 inverseJoinColumns={@JoinColumn(name="USER_ID")}) 50 public List<User> getUsers() { 51 return users; 52 } 53 54 public void setUsers(List<User> users) { 55 this.users = users; 56 } 57 58 @Override 59 public String toString() { 60 return "Role [id=" + id + ", role=" + role + ", users=" + users + "]"; 61 } 62 63 }
以上这些注解都是由ejb3-persistence.jar提供
以上是在实体类中的对ejb3提供的注释的用法,接下来就是对JDBC的封装了,利用泛型和反射我们要做的就是实现一个基类BaseDao.Java,让所有继承了这个基类的导出类都能拥有对应的增删查改,下面这个基类就是我针对JDBC结合ejb3做的封装,目地就是为了让JDBC的使用变得更加简便,不再只是面向过程,代码中已经提供了对外接口的注释
1 package com.topview.dao; 2 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 import java.sql.Connection; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultSet; 9 import java.sql.SQLException; 10 import java.util.ArrayList; 11 import java.util.Collection; 12 import java.util.HashMap; 13 import java.util.List; 14 import java.util.Map; 15 16 import javax.persistence.Column; 17 import javax.persistence.Id; 18 import javax.persistence.JoinColumn; 19 import javax.persistence.JoinTable; 20 import javax.persistence.ManyToMany; 21 import javax.persistence.ManyToOne; 22 import javax.persistence.OneToMany; 23 import javax.persistence.OneToOne; 24 import javax.persistence.Table; 25 26 27 /** 28 * Dao层的抽象父类,已对JDBC进行了一定的封装 29 * @author LinBingcheng<494410479@qq.com> 30 * @date 2014年7月29日 31 * @CopyRight 2014 Topview Inc 32 * @version v2.0 33 */ 34 public class BaseDao<T> { 35 36 private Connection connection; 37 38 39 /** 40 * 数据添加,删除,修改 41 * @param sql 需要执行的SQL语句 42 * @param params SQL语句对应的参数 43 * @return 操作成功:true<br/> 44 * 操作失败:false 45 * @throws Exception 46 */ 47 public boolean executeUpdate(String sql, Object... params) throws Exception { 48 PreparedStatement pstmt = null; 49 pstmt = connection.prepareStatement(sql); 50 for (int i = 0; i < params.length; i++) { 51 pstmt.setObject(i + 1, params[i]); 52 } 53 pstmt.executeUpdate(); 54 pstmt.close(); 55 return true; 56 } 57 58 /** 59 * 数据添加 60 * @param entity 泛型的实体类对象 61 * @return 添加成功:true<br/> 62 * 添加失败:false 63 * @throws Exception 64 */ 65 public boolean add(T entity) throws Exception { 66 int i = 1; 67 PreparedStatement pstmt = null; 68 String insetSql = "INSERT INTO " + getTableName(entity) + " ("; 69 String valueSql = "VALUES ("; 70 Map<String, Object> name_value = new HashMap<String, Object>(); 71 name_value.putAll(getName_ValuesOfColumn(entity)); 72 name_value.putAll(getName_EntityIdOfJoinColumn(entity)); 73 for (String name : name_value.keySet()) { 74 insetSql = insetSql + name + ","; 75 valueSql = valueSql + "?,"; 76 } 77 insetSql = insetSql.substring(0, insetSql.length() - 1) + ")" 78 + valueSql.substring(0, valueSql.length() - 1) + ")"; 79 System.out.println("insetSql:" + insetSql); 80 pstmt = connection.prepareStatement(insetSql); 81 for (String name : name_value.keySet()) { 82 pstmt.setObject(i++, name_value.get(name)); 83 } 84 pstmt.executeUpdate(); 85 pstmt.close(); 86 insetJoinTable(entity); 87 return true; 88 } 89 90 /** 91 * 数据删除 92 * @param entity 实体类对象,内部存放着需要进行删除匹配的数据,其他的不用 93 * @return 删除成功:true<br/> 94 * 删除失败:false 95 * @throws Exception 96 */ 97 public boolean delete(T entity) throws Exception { 98 int i = 0; 99 String deleteSql = "DELETE FROM " + getTableName(entity); 100 String where = " WHERE"; 101 PreparedStatement pstmt = null; 102 Map<String, Object> name_value = new HashMap<String, Object>(); 103 Object entityId = getEntityId(entity); 104 name_value.putAll(getName_ValuesOfColumn(entity)); 105 name_value.putAll(getName_EntityIdOfJoinColumn(entity)); 106 for (String name : name_value.keySet()) { 107 if (name_value.get(name).equals(entityId) && entityId != null) { 108 where = where + " " + name + " = ?"; 109 i = 1; 110 break; 111 } 112 } 113 if (i == 0) { 114 for (String name : name_value.keySet()) { 115 if (name_value.get(name) != null) { 116 where = where + " " + name + " = ? AND"; 117 } 118 } 119 where = where.substring(0, where.length() - 3); 120 } 121 deleteSql = deleteSql + where; 122 System.out.println("deleteSql:" + deleteSql); 123 pstmt = connection.prepareStatement(deleteSql); 124 if (i == 1) { 125 pstmt.setObject(i, entityId); 126 } else { 127 i = 1; 128 for (String name : name_value.keySet()) { 129 pstmt.setObject(i++, name_value.get(name)); 130 } 131 } 132 pstmt.executeUpdate(); 133 pstmt.close(); 134 return true; 135 } 136 137 /** 138 * 数据修改 139 * @param entity 实体类对象 140 * @return 修改成功:true<br/> 141 * 修改失败:false 142 * @throws Exception 143 */ 144 public boolean update(T entity) throws Exception { 145 int i = 1; 146 String updateSql = "UPDATE " + getTableName(entity) + " SET "; 147 String where = " WHERE"; 148 PreparedStatement pstmt = null; 149 Map<String, Object> name_value = new HashMap<String, Object>(); 150 151 Object entityId = getEntityId(entity); 152 name_value.putAll(getName_ValuesOfColumn(entity)); 153 name_value.putAll(getName_EntityIdOfJoinColumn(entity)); 154 for (String name : name_value.keySet()) { 155 if (name_value.get(name).equals(entityId)) { 156 where = where + " " + name + " = ?"; 157 } else { 158 updateSql = updateSql + " " + name + " = ? ,"; 159 } 160 } 161 updateSql = updateSql.substring(0, updateSql.length() - 1); 162 updateSql = updateSql + where; 163 System.out.println("updateSql:" + updateSql); 164 pstmt = connection.prepareStatement(updateSql); 165 for (String name : name_value.keySet()) { 166 if (!name_value.get(name).equals(entityId)) { 167 pstmt.setObject(i++, name_value.get(name)); 168 } 169 } 170 pstmt.setObject(i, entityId); 171 pstmt.executeUpdate(); 172 pstmt.close(); 173 174 return true; 175 } 176 177 178 /** 179 * 数据查询 180 * @param object 实体类对象 181 * @return 查询到的List 182 * @throws Exception 183 */ 184 @SuppressWarnings("unchecked") 185 public List<T> find(T object) throws Exception { 186 int i = 1; 187 List<T> list = new ArrayList<T>(); 188 PreparedStatement pstmt = null; 189 ResultSet re = null; 190 String findSql = "SELECT * FROM " + getTableName(object) + " WHERE"; 191 String where = ""; 192 Map<String, Object> name_value = new HashMap<String, Object>(); 193 Map<String, Object> name_entityId = getName_EntityIdOfJoinColumn(object); 194 name_value.putAll(getName_ValuesOfColumn(object)); 195 name_value.putAll(name_entityId); 196 for (String name : name_value.keySet()) { 197 if (name_value.get(name) != null) { 198 where = where + " " + name + " = ? AND"; 199 } 200 } 201 if (where.length() != 0) { 202 where = where.substring(0, where.length() - 3); 203 findSql = findSql + where; 204 } else { 205 findSql = findSql.substring(0, findSql.length() - 5); 206 } 207 System.out.println("findSql:" + findSql); 208 pstmt = connection.prepareStatement(findSql); 209 for (String name : name_value.keySet()) { 210 if (name_value.get(name) != null) { 211 pstmt.setObject(i++, name_value.get(name)); 212 } 213 } 214 re = pstmt.executeQuery(); 215 while (re.next()) { 216 Object o = object.getClass().newInstance(); 217 Map<String, Field> name_fields = getName_FieldsOfColumn(o); 218 for (String name : name_fields.keySet()) { 219 Field field = name_fields.get(name); 220 field.setAccessible(true); 221 field.set(o, re.getObject(name)); 222 } 223 setOneToManyMap(o); 224 for (String cloumnName : name_entityId.keySet()) { 225 setOneToOneMap(o, cloumnName, re.getObject(cloumnName)); 226 setManyToOneMap(o, cloumnName, re.getObject(cloumnName)); 227 } 228 setManyToManyMap(o); 229 list.add((T) o); 230 } 231 re.close(); 232 pstmt.close(); 233 return list; 234 } 235 236 237 /** 238 * 数据查询,可添加模糊,分页查询操作 239 * @param object 实体类对象 240 * @param conditionSQL 进行模糊查询和分页操作的的SQL语句, 241 * @param params 进行模糊查询和分页操作的参数 242 * @return 查询到的List 243 * @throws Exception 244 */ 245 @SuppressWarnings("unchecked") 246 public List<T> SQLQuery(T object, String conditionSQL, Object... params) 247 throws Exception { 248 int i = 1; 249 List<T> list = new ArrayList<T>(); 250 PreparedStatement pstmt = null; 251 ResultSet re = null; 252 String findSql = "SELECT * FROM " + getTableName(object) + " WHERE"; 253 String where = ""; 254 Map<String, Object> name_value = new HashMap<String, Object>(); 255 Map<String, Object> name_entityId = getName_EntityIdOfJoinColumn(object); 256 name_value.putAll(getName_ValuesOfColumn(object)); 257 name_value.putAll(name_entityId); 258 for (String name : name_value.keySet()) { 259 if (name_value.get(name) != null) { 260 where = where + " " + name + " = ? AND"; 261 } 262 } 263 if (where.length() != 0) { 264 where = where.substring(0, where.length() - 3); 265 findSql = findSql + where; 266 } else { 267 findSql = findSql.substring(0, findSql.length() - 5); 268 } 269 findSql = findSql + conditionSQL; 270 System.out.println("findSql" + findSql); 271 pstmt = connection.prepareStatement(findSql); 272 for (String name : name_value.keySet()) { 273 if (name_value.get(name) != null) { 274 pstmt.setObject(i++, name_value.get(name)); 275 } 276 } 277 278 for (Object o : params) { 279 pstmt.setObject(i++, o); 280 } 281 282 re = pstmt.executeQuery(); 283 while (re.next()) { 284 Object o = object.getClass().newInstance(); 285 Map<String, Field> name_fields = getName_FieldsOfColumn(o); 286 for (String name : name_fields.keySet()) { 287 Field field = name_fields.get(name); 288 field.setAccessible(true); 289 field.set(o, re.getObject(name)); 290 } 291 setOneToManyMap(o); 292 for (String cloumnName : name_entityId.keySet()) { 293 setOneToOneMap(o, cloumnName, re.getObject(cloumnName)); 294 setManyToOneMap(o, cloumnName, re.getObject(cloumnName)); 295 } 296 setManyToManyMap(o); 297 list.add((T) o); 298 } 299 re.close(); 300 pstmt.close(); 301 return list; 302 } 303 304 private List<Object> query(Class<?> clazz, String findSql, Object... params) 305 throws InstantiationException, IllegalAccessException, 306 SQLException, NoSuchFieldException, SecurityException { 307 int i = 1; 308 List<Object> list = new ArrayList<Object>(); 309 PreparedStatement pstmt = null; 310 ResultSet re = null; 311 pstmt = connection.prepareStatement(findSql); 312 for (Object object : params) { 313 pstmt.setObject(i++, object); 314 } 315 re = pstmt.executeQuery(); 316 while (re.next()) { 317 Object o = clazz.newInstance(); 318 Map<String, Field> name_fields = getName_FieldsOfColumn(o); 319 for (String name : name_fields.keySet()) { 320 Field field = name_fields.get(name); 321 field.setAccessible(true); 322 field.set(o, re.getObject(name)); 323 } 324 list.add(o); 325 } 326 re.close(); 327 params.clone(); 328 return list; 329 } 330 331 private void setOneToOneMap(Object object, String cloumnName, Object value) 332 throws NoSuchFieldException, SecurityException, 333 InstantiationException, IllegalAccessException, SQLException, 334 IllegalArgumentException, InvocationTargetException { 335 Method[] methods = object.getClass().getDeclaredMethods(); 336 for (Method method : methods) { 337 if (method.isAnnotationPresent(OneToOne.class) 338 && !method.isAnnotationPresent(JoinColumn.class)) { 339 OneToOne oneToOne = method.getAnnotation(OneToOne.class); 340 Class<?> clazz = oneToOne.targetEntity(); 341 String mappedBy = oneToOne.mappedBy(); 342 Object o = clazz.newInstance(); 343 String findSql = "SELECT * FROM " + getTableName(o) + " WHERE " 344 + mappedBy + " = ?"; 345 // System.out.println("findSql" + findSql); 346 List<?> list = query(clazz, findSql, getEntityId(object)); 347 if (!list.isEmpty() && list != null) { 348 o = query(clazz, findSql, getEntityId(object)).get(0); 349 StringBuffer s = new StringBuffer(method.getName() 350 .toString()); 351 String fieldsName = s.substring(3).toLowerCase(); 352 Field field = object.getClass() 353 .getDeclaredField(fieldsName); 354 field.setAccessible(true); 355 field.set(object, o); 356 } 357 } 358 if (method.isAnnotationPresent(OneToOne.class) 359 && method.getAnnotation(JoinColumn.class).name() 360 .equals(cloumnName)) { 361 OneToOne oneToOne = method.getAnnotation(OneToOne.class); 362 Class<?> clazz = oneToOne.targetEntity(); 363 String mappedBy = oneToOne.mappedBy(); 364 Object o = clazz.newInstance(); 365 String findSql = "SELECT * FROM " + getTableName(o) + " WHERE " 366 + mappedBy + " = ?"; 367 // System.out.println("findSql:" + findSql); 368 List<?> list = query(clazz, findSql, value); 369 if (!list.isEmpty() && list != null) { 370 o = list.get(0); 371 StringBuffer s = new StringBuffer(method.getName() 372 .toString()); 373 String fieldsName = s.substring(3).toLowerCase(); 374 Field field = object.getClass() 375 .getDeclaredField(fieldsName); 376 field.setAccessible(true); 377 field.set(object, o); 378 } 379 } 380 } 381 } 382 383 private void setOneToManyMap(Object object) throws InstantiationException, 384 IllegalAccessException, NoSuchFieldException, SecurityException, 385 SQLException, IllegalArgumentException, InvocationTargetException { 386 Method[] methods = object.getClass().getDeclaredMethods(); 387 for (Method method : methods) { 388 if (method.isAnnotationPresent(OneToMany.class) 389 && !method.isAnnotationPresent(JoinColumn.class)) { 390 OneToMany oneToMany = method.getAnnotation(OneToMany.class); 391 Class<?> clazz = oneToMany.targetEntity(); 392 String mappedBy = oneToMany.mappedBy(); 393 Object o = clazz.newInstance(); 394 String findSql = "SELECT * FROM " + getTableName(o) + " WHERE " 395 + mappedBy + " = ?"; 396 // System.out.println("findSql:" + findSql); 397 o = query(clazz, findSql, getEntityId(object)); 398 StringBuffer s = new StringBuffer(method.getName().toString()); 399 String fieldsName = s.substring(3).toLowerCase(); 400 Field field = object.getClass().getDeclaredField(fieldsName); 401 field.setAccessible(true); 402 field.set(object, o); 403 } 404 } 405 } 406 407 private void setManyToOneMap(Object object, String cloumnName, Object value) 408 throws InstantiationException, IllegalAccessException, 409 NoSuchFieldException, SecurityException, SQLException { 410 Method[] methods = object.getClass().getDeclaredMethods(); 411 for (Method method : methods) { 412 if (method.isAnnotationPresent(ManyToOne.class) 413 && method.isAnnotationPresent(JoinColumn.class) 414 && method.getAnnotation(JoinColumn.class).name() 415 .equals(cloumnName)) { 416 ManyToOne manyToOne = method.getAnnotation(ManyToOne.class); 417 Class<?> clazz = manyToOne.targetEntity(); 418 Object o = clazz.newInstance(); 419 String mappedByColumn = getEntityIdColumn(object); 420 String findSql = "SELECT * FROM " + getTableName(o) + " WHERE " 421 + mappedByColumn + " = ?"; 422 // System.out.println("findSql:" + findSql); 423 o = query(clazz, findSql, value).get(0); 424 StringBuffer s = new StringBuffer(method.getName().toString()); 425 String fieldsName = s.substring(3).toLowerCase(); 426 Field field = object.getClass().getDeclaredField(fieldsName); 427 field.setAccessible(true); 428 field.set(object, o); 429 } 430 } 431 } 432 433 434 private void setManyToManyMap(Object object) throws SQLException, 435 InstantiationException, IllegalAccessException, 436 NoSuchFieldException, SecurityException, IllegalArgumentException, 437 InvocationTargetException { 438 Method[] methods = object.getClass().getDeclaredMethods(); 439 for (Method method : methods) { 440 if (method.isAnnotationPresent(ManyToMany.class) 441 && method.isAnnotationPresent(JoinTable.class)) { 442 ManyToMany manyToMany = method.getAnnotation(ManyToMany.class); 443 JoinTable joinTable = method.getAnnotation(JoinTable.class); 444 List<Object> list = new ArrayList<Object>(); 445 Class<?> clazz = manyToMany.targetEntity(); 446 Object o = clazz.newInstance(); 447 String joinTableName = joinTable.name(); 448 String JoinColumnName = joinTable.joinColumns()[0].name(); 449 String inverseJoinColumnsName = joinTable.inverseJoinColumns()[0] 450 .name(); 451 Object JoinColumnValue = getEntityId(object); 452 String findMapSql = "SELECT * FROM " + joinTableName 453 + " WHERE " + JoinColumnName + " = ?"; 454 // System.out.println("findMapSql" + findMapSql); 455 String findSql = "SELECT * FROM " + getTableName(o) + " WHERE " 456 + getEntityIdColumn(o) + " = ?"; 457 // System.out.println("findSql:" + findSql); 458 PreparedStatement pstmt = connection 459 .prepareStatement(findMapSql); 460 pstmt.setObject(1, JoinColumnValue); 461 ResultSet re = pstmt.executeQuery(); 462 while (re.next()) { 463 list.add(query(clazz, findSql, 464 re.getObject(inverseJoinColumnsName))); 465 } 466 StringBuffer s = new StringBuffer(method.getName().toString()); 467 String fieldsName = s.substring(3).toLowerCase(); 468 Field field = object.getClass().getDeclaredField(fieldsName); 469 field.setAccessible(true); 470 field.set(object, list); 471 re.close(); 472 pstmt.close(); 473 } 474 } 475 } 476 477 @SuppressWarnings("unchecked") 478 private void insetJoinTable(Object object) throws SQLException, 479 IllegalAccessException, IllegalArgumentException, 480 InvocationTargetException { 481 Object JoinColumnValue = getEntityId(object); 482 Method[] methods = object.getClass().getDeclaredMethods(); 483 for (Method method : methods) { 484 if (method.isAnnotationPresent(JoinTable.class)) { 485 if (method.invoke(object) != null) { 486 JoinTable joinTable = method.getAnnotation(JoinTable.class); 487 String joinTableName = joinTable.name(); 488 String JoinColumnName = joinTable.joinColumns()[0].name(); 489 String inverseJoinColumnsName = joinTable 490 .inverseJoinColumns()[0].name(); 491 String insertSql = "INSERT INTO " + joinTableName + " (" 492 + JoinColumnName + ", " + inverseJoinColumnsName 493 + ")" + "VALUES (?, ?)"; 494 // System.out.println("insertSql:" + insertSql); 495 Collection<Object> collection = (Collection<Object>) method 496 .invoke(object); 497 for (Object o : collection) { 498 PreparedStatement pstmt = connection 499 .prepareStatement(insertSql); 500 Object inverseJoinColumnsValue = getEntityId(o); 501 pstmt.setObject(1, JoinColumnValue); 502 pstmt.setObject(2, inverseJoinColumnsValue); 503 pstmt.executeUpdate(); 504 pstmt.close(); 505 } 506 } 507 } 508 } 509 } 510 511 512 513 514 private String getEntityIdColumn(Object object){ 515 Method[] methods = object.getClass().getDeclaredMethods(); 516 for (Method method : methods) { 517 if (method.isAnnotationPresent(Id.class)) { 518 Column column = method.getAnnotation(Column.class); 519 return column.name(); 520 } 521 } 522 return null; 523 } 524 525 526 527 private Map<String, Object> getName_EntityIdOfJoinColumn(Object object) 528 throws IllegalAccessException, IllegalArgumentException, 529 InvocationTargetException { 530 Map<String, Object> name_id = new HashMap<String, Object>(); 531 Method[] methods = object.getClass().getDeclaredMethods(); 532 for (Method method : methods) { 533 if (method.isAnnotationPresent(JoinColumn.class)) { 534 JoinColumn joinColumn = method.getAnnotation(JoinColumn.class); 535 String column = joinColumn.name(); 536 Object entity = method.invoke(object); 537 Object entityId = getEntityId(entity); 538 name_id.put(column, entityId); 539 } 540 } 541 return name_id; 542 } 543 544 private Map<String, Field> getName_FieldsOfColumn(Object object) 545 throws NoSuchFieldException, SecurityException { 546 Map<String, Field> name_fields = new HashMap<String, Field>(); 547 Method[] methods = object.getClass().getDeclaredMethods(); 548 for (Method method : methods) { 549 if (method.isAnnotationPresent(Column.class)) { 550 Column column = method.getAnnotation(Column.class); 551 String name = column.name(); 552 StringBuffer s = new StringBuffer(method.getName().toString()); 553 String fieldsName = s.substring(3, 4).toLowerCase() 554 + s.substring(4); 555 Field field = object.getClass().getDeclaredField(fieldsName); 556 name_fields.put(name, field); 557 } 558 } 559 return name_fields; 560 } 561 562 private Map<String, Object> getName_ValuesOfColumn(Object object) 563 throws IllegalAccessException, IllegalArgumentException, 564 InvocationTargetException { 565 Map<String, Object> name_value = new HashMap<String, Object>(); 566 Method[] methods = object.getClass().getDeclaredMethods(); 567 for (Method method : methods) { 568 if (method.isAnnotationPresent(Column.class)) { 569 Column column = method.getAnnotation(Column.class); 570 String columnName = column.name(); 571 Object columnValue = method.invoke(object); 572 name_value.put(columnName, columnValue); 573 } 574 } 575 return name_value; 576 } 577 578 private Object getEntityId(Object object) throws IllegalAccessException, 579 IllegalArgumentException, InvocationTargetException { 580 if (object != null) { 581 Method[] methods = object.getClass().getDeclaredMethods(); 582 for (Method method : methods) { 583 if (method.isAnnotationPresent(Id.class)) { 584 return method.invoke(object); 585 } 586 } 587 } 588 return null; 589 } 590 591 private String getTableName(Object object) { 592 String name = null; 593 if (object.getClass().isAnnotationPresent(Table.class)) { 594 Table table = object.getClass().getAnnotation(Table.class); 595 name = table.name(); 596 } 597 if (name == null) {//此乃默认 598 name = object.getClass().getName(); 599 int i = name.lastIndexOf("."); 600 name = name.substring(i + 1).toUpperCase(); 601 } 602 return name; 603 } 604 605 public Connection getConnection() { 606 return connection; 607 } 608 609 public void setConnection(Connection connection) { 610 this.connection = connection; 611 } 612 613 }
下面说明这个封装类的用法,数据库持久层的所有实现类只要直接继承这个BaseDao.java,泛型用对应是实体类代替,就算完成了,改类就已经有了相应的增删查改的功能,我们还可以根据需要继续对相应是实现类对已有的方法进行组合增加自己的对象都有的方法
下面就是我根据上面实体类添加的类的方法
1 package com.dao; 2 3 import java.util.List; 4 5 import com.po.User; 6 7 public class UserDao extends BaseDao<User> { 8 9 /** 10 * 查询一个用户 11 * @param user 拥有对应的查询必备的条件 12 * @return User对象 13 * @throws Exception 14 */ 15 public User getUser(User user) throws Exception { 16 List<User> users = find(user); 17 if (users == null || users.isEmpty()) 18 return null; 19 return find(user).get(0); 20 } 21 22 }
1 package com.dao; 2 3 import com.po.Info; 4 5 public class InfoDao extends BaseDao<Info> { 6 7 }
1 package com.dao; 2 3 import com.po.Book; 4 5 public class BookDao extends BaseDao<Book> { 6 7 }
package com.dao; import com.po.Role; public class RoleDao extends BaseDao<Role> { }
下面是方法的测试演示
1 package com.test; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.sql.Connection; 5 import java.sql.SQLException; 6 import java.util.Date; 7 import java.util.List; 8 9 import org.junit.Test; 10 11 import com.dao.BookDao; 12 import com.dao.InfoDao; 13 import com.dao.RoleDao; 14 import com.dao.UserDao; 15 import com.po.Book; 16 import com.po.Info; 17 import com.po.Role; 18 import com.po.User; 19 import com.service.UserService; 20 import com.service.impl.UserServiceImpl; 21 import com.util.DBManager; 22 import com.util.UUIDUtil; 23 24 public class MyTest { 25 26 @Test 27 public void testAddUser() throws SQLException { 28 //测试添加 29 try { 30 Connection conn = DBManager.getConnection(); 31 UserDao userDao = new UserDao(); 32 userDao.setConnection(conn); 33 User user = new User(); 34 for (int i = 0; i < 10; i++) { 35 user.setId(UUIDUtil.getUUID()); 36 user.setName("测试" + i); 37 user.setDate(new Date()); 38 userDao.add(user); 39 } 40 DBManager.close(conn); 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } 44 } 45 46 @Test 47 public void testUpdateAndFindUser() { 48 //测试修改和查找 49 try { 50 Connection conn = DBManager.getConnection(); 51 UserDao userDao = new UserDao(); 52 userDao.setConnection(conn); 53 List<User> users = userDao.find(new User());//传空对象会全部查出来的,可任意set查找条件进去 54 for (User user : users) { 55 user.setName("ceshi"); 56 userDao.update(user); 57 } 58 DBManager.close(conn); 59 } catch (Exception e) { 60 e.printStackTrace(); 61 } 62 63 } 64 65 @Test 66 public void testDeleteAndGetUser(){ 67 //测试删除和查找 68 try { 69 Connection conn = DBManager.getConnection(); 70 UserDao userDao = new UserDao(); 71 userDao.setConnection(conn); 72 User user = userDao.getUser(new User()); 73 userDao.delete(user); 74 DBManager.close(conn); 75 } catch (Exception e) { 76 e.printStackTrace(); 77 } 78 } 79 80 @Test 81 public void testRelevanceInset(){ 82 // 测试一对一,多对一,多对多关联插入 83 try { 84 Connection conn = DBManager.getConnection(); 85 UserDao userDao = new UserDao(); 86 InfoDao infoDao = new InfoDao(); 87 RoleDao roleDao = new RoleDao(); 88 BookDao bookDao = new BookDao(); 89 userDao.setConnection(conn); 90 infoDao.setConnection(conn); 91 roleDao.setConnection(conn); 92 bookDao.setConnection(conn); 93 Info info = new Info(); 94 List<User> users = userDao.find(new User());//一对一关联插入 95 for (User user : users) { 96 info.setUser(user); 97 info.setInfo("info"); 98 info.setId(UUIDUtil.getUUID()); 99 infoDao.add(info); 100 } 101 User user = userDao.getUser(new User()); 102 for (int i = 0; i < 10; i++) {//多对一关联插入 103 Book book = new Book(); 104 book.setId(UUIDUtil.getUUID()); 105 book.setBookName("书名"); 106 book.setUser(user); 107 bookDao.add(book); 108 } 109 List<Role> roles = roleDao.find(new Role(1,null));//多对多关联插入 110 user.setId(UUIDUtil.getUUID());//主键不能一样 111 user.setRoles(roles); 112 userDao.add(user); 113 DBManager.close(conn); 114 } catch (Exception e) { 115 e.printStackTrace(); 116 } 117 } 118 119 @Test 120 public void testRelevanceFind(){ 121 try { 122 Connection conn = DBManager.getConnection(); 123 UserDao userDao = new UserDao(); 124 InfoDao infoDao = new InfoDao(); 125 RoleDao roleDao = new RoleDao(); 126 BookDao bookDao = new BookDao(); 127 userDao.setConnection(conn); 128 infoDao.setConnection(conn); 129 roleDao.setConnection(conn); 130 bookDao.setConnection(conn); 131 List<User> users = userDao.find(new User()); 132 for (User user : users) { 133 System.out.println(user); 134 } 135 List<Info> infos = infoDao.find(new Info()); 136 for (Info info : infos) { 137 System.out.println(info); 138 } 139 List<Role> roles = roleDao.find(new Role(1,null)); 140 for (Role role : roles) { 141 System.out.println(role); 142 } 143 List<Book> books = bookDao.find(new Book()); 144 for (Book book : books) { 145 System.out.println(book); 146 } 147 DBManager.close(conn); 148 } catch (Exception e) { 149 e.printStackTrace(); 150 } 151 } 152 153 }
另外还有提供模糊查询和分页操作的接口,提供给使用扩展