package com.rlovep.ann; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.dbutils.ResultSetHandler; import com.peace.generic.Jdbc_Utils; import com.rlovep.ann.util.Column; import com.rlovep.ann.util.Id; import com.rlovep.ann.util.Table; /** * 解决优化的问题: * 1. 当数据库表名与类名不一致、 * 2. 字段与属性不一样、 * 3. 主键不叫id * */ public class BaseDao<T> { //当前运行的类型 private Class<T>clazz; //表名 private String tableName; //主键 private String id; public BaseDao() { // 获得父类type 此处为参数类型 BaseDao<Admin> Type type = this.getClass().getGenericSuperclass(); // 强制转换为“参数化类型” 【BaseDao<Admin>】 ParameterizedType pType = (ParameterizedType) type; // 获取参数化类型中,实际类型的定义 【new Type[]{Admin.class}】 Type[] aTypes = pType.getActualTypeArguments(); // 获取数据的第一个元素:Admin.class clazz = (Class) aTypes[0]; //获得表名注解 Table annotation = clazz.getAnnotation(Table.class); tableName=annotation.tableName(); //获取当前运行类的所有字段、遍历、获取每一个字段上的id注解 Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { // 设置强制访问 f.setAccessible(true); // 获取每一个字段上的id注解 Id anno_id = f.getAnnotation(Id.class); // 判断 if (anno_id != null) { // 如果字段上有id注解,当前字段(field)是主键; 再获取字段名称 Column column = f.getAnnotation(Column.class); // 主键 id = column.columnName(); // 跳出循环 break; } } System.out.println("表名"+tableName); System.out.println("ID:"+id); } public T findById(int sid){ try { String sql = "select * from " + tableName + " where " + id +"=?"; /* * DbUtils的已经封装好的工具类:BeanHandler? 属性=字段 */ return Jdbc_Utils.getQurrRunner().query(sql, new BeanHandler<T>(clazz), sid); } catch (Exception e) { throw new RuntimeException(e); } } public List<T> getAll(){ try { String sql = "select * from " + tableName; return Jdbc_Utils.getQurrRunner().query(sql, new BeanListHandler<T>(clazz)); } catch (Exception e) { throw new RuntimeException(e); } } } /** * 自定义结果集:封装单个Bean对象 */ class BeanHandler<T> implements ResultSetHandler<T>{ private Class<T> clazz; public BeanHandler(Class<T> clazz){ this.clazz=clazz; } @Override public T handle(ResultSet rs) throws SQLException { try { //创建要封装的对象 T t=clazz.newInstance(); //判断是否返回结果 if(rs.next()) { //获得class的field Field[] fields = clazz.getDeclaredFields(); //遍历所有fields for(Field f:fields) { //获得属性名 String fieldName=f.getName(); //获得属性的cloume注释 Column column = f.getAnnotation(Column.class); //从rs中获得相应的结果 Object object = rs.getObject(column.columnName()); //设置对象的属性值 BeanUtils.copyProperty(t, fieldName, object); } } return t; } catch (Exception e) { throw new RuntimeException(e); } } } /** * 自定义结果集:封装多个Bean对象到List集合 */ class BeanListHandler<T> implements ResultSetHandler<List<T>>{ // 要封装的单个对象 private Class<T> clazz; public BeanListHandler(Class<T> clazz){ this.clazz = clazz; } @Override public List<T> handle(ResultSet rs) throws SQLException { List<T> list=new ArrayList<>(); try { while(rs.next()) { // 创建要封装的对象 ‘1’ T t = clazz.newInstance(); // a. 获取类的所有的Field字段数组 Field[] fs = clazz.getDeclaredFields(); // b. 遍历, 得到每一个字段类型:Field for (Field f : fs) { // c. 获取”属性名称“ String fieldName = f.getName(); // e. 获取Field字段上注解 【@Column(columnName = "a_userName")】 Column column = f.getAnnotation(Column.class); // f. ”字段名“ String columnName = column.columnName(); // 数据库中字段 a_userName // g. 字段值 Object columnValue = rs.getObject(columnName); // 设置(BeanUtils组件) BeanUtils.copyProperty(t, fieldName, columnValue); } // 对象添加到集合 list.add(t); } return list; } catch (Exception e) { throw new RuntimeException(e); } } }