想飞的程序员

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  • 实体Admin,与数据库字段名不同,添加注释。
 1 import cn.itcast.utils.Column;
 2 import cn.itcast.utils.Id;
 3 import cn.itcast.utils.Table;
 4 
 5 // Admin=a_admin
 6 @Table(tableName="a_admin")
 7 public class Admin {
 8 
 9     @Id
10     @Column(columnName = "a_id")
11     private int id;
12     
13     @Column(columnName = "a_userName")
14     private String userName;
15     
16     @Column(columnName = "a_pwd")
17     private String pwd;
18     
19     public int getId() {
20         return id;
21     }
22     public void setId(int id) {
23         this.id = id;
24     }
25     public String getUserName() {
26         return userName;
27     }
28     public void setUserName(String userName) {
29         this.userName = userName;
30     }
31     public String getPwd() {
32         return pwd;
33     }
34     public void setPwd(String pwd) {
35         this.pwd = pwd;
36     }
37     @Override
38     public String toString() {
39         return "Admin [id=" + id + ", pwd=" + pwd + ", userName=" + userName
40                 + "]";
41     }
42     
43 }

 

  • Column.java  注释类
 2 
 3 import java.lang.annotation.Retention;
 4 import java.lang.annotation.RetentionPolicy;
 5 import java.lang.annotation.Target;
 6 import static java.lang.annotation.ElementType.FIELD;
 7 
 8 /**
 9  * 描述一个字段
10  * @author Jie.Yuan
11  *
12  */
13 @Target({FIELD})
14 @Retention(RetentionPolicy.RUNTIME)  // 指定注解在运行时期有效
15 public @interface Column {
16 
17     String columnName();
18 }

 

  • Id.java
 1 import static java.lang.annotation.ElementType.FIELD;
 2 
 3 import java.lang.annotation.Retention;
 4 import java.lang.annotation.RetentionPolicy;
 5 import java.lang.annotation.Target;
 6 
 7 /**
 8  * 描述一个主键字段
 9  * @author Jie.Yuan
10  *
11  */
12 @Target({FIELD})
13 @Retention(RetentionPolicy.RUNTIME)  // 指定注解在运行时期有效
14 public @interface Id {
15 
16 }

 

  • Table.java
 1 import static java.lang.annotation.ElementType.TYPE;
 2 
 3 import java.lang.annotation.Retention;
 4 import java.lang.annotation.RetentionPolicy;
 5 import java.lang.annotation.Target;
 6 
 7 /**
 8  * 注解,描述表名称
 9  * @author Jie.Yuan
10  *
11  */
12 @Target({TYPE})
13 @Retention(RetentionPolicy.RUNTIME)  // 指定注解在运行时期有效
14 public @interface Table {
15 
16     String tableName();
17 }

 

  • BaseDao.java
  1 import java.lang.reflect.Field;
  2 import java.lang.reflect.ParameterizedType;
  3 import java.lang.reflect.Type;
  4 import java.sql.ResultSet;
  5 import java.sql.SQLException;
  6 import java.util.ArrayList;
  7 import java.util.List;
  8 
  9 import org.apache.commons.beanutils.BeanUtils;
 10 import org.apache.commons.dbutils.ResultSetHandler;
 11 
 12 import cn.itcast.b_reflect.JdbcUtils;
 13 import cn.itcast.utils.Column;
 14 import cn.itcast.utils.Id;
 15 import cn.itcast.utils.Table;
 16 
 17 /**
 18  * 解决优化的问题:
 19  *       1. 当数据库表名与类名不一致、 
 20  *    2. 字段与属性不一样、
 21  *    3. 主键不叫id 
 22  *    
 23  */
 24 public class BaseDao<T> {
 25     
 26     // 当前运行类的类型
 27     private Class<T> clazz;
 28     // 表名
 29     private String tableName;
 30     // 主键
 31     private String id_primary;
 32 
 33     // 拿到当前运行类的参数化类型中实际的类型  ( BaseDao<Admin> ,  Admin.class)
 34     public BaseDao(){
 35         Type type = this.getClass().getGenericSuperclass();
 36         ParameterizedType pt = (ParameterizedType) type;
 37         Type[] types = pt.getActualTypeArguments();
 38         clazz = (Class<T>) types[0];
 39         
 40         //已经拿到:  Admin.class
 41         
 42         /*******1. 获取表名*******/
 43         Table table = clazz.getAnnotation(Table.class);
 44         tableName = table.tableName();
 45         
 46         /*******2. 获取主键字段*******/
 47         //获取当前运行类的所有字段、遍历、获取每一个字段上的id注解
 48         Field[] fs = clazz.getDeclaredFields();
 49         for (Field f : fs) {
 50             
 51             // 设置强制访问
 52             f.setAccessible(true);
 53             
 54             // 获取每一个字段上的id注解
 55             Id anno_id = f.getAnnotation(Id.class);
 56             
 57             // 判断
 58             if (anno_id != null) {
 59                 // 如果字段上有id注解,当前字段(field)是主键; 再获取字段名称
 60                 Column column = f.getAnnotation(Column.class);
 61                 // 主键
 62                 id_primary = column.columnName();
 63                 // 跳出循环
 64                 break;
 65             }
 66         }
 67         
 68         System.out.println("表:" + tableName);
 69         System.out.println("主键:" + id_primary);
 70     }
 71     
 72     
 73     public T findById(int id){
 74         try {
 75             String sql = "select * from " + tableName + " where " + id_primary +"=?";
 76             /*
 77              * DbUtils的已经封装好的工具类:BeanHandler?   属性=字段
 78              */
 79             return JdbcUtils.getQuerrRunner().query(sql, new BeanHandler<T>(clazz), id);
 80         } catch (Exception e) {
 81             throw new RuntimeException(e);
 82         }
 83     }
 84     
 85     
 86     public List<T> getAll(){
 87         try {
 88             String sql = "select * from " + tableName;
 89             return JdbcUtils.getQuerrRunner().query(sql, new BeanListHandler<T>(clazz));
 90         } catch (Exception e) {
 91             throw new RuntimeException(e);
 92         }
 93     }
 94     
 95 }
 96 
 97 /**
 98  * 自定义结果集:封装单个Bean对象
 99  */
100 class BeanHandler<T> implements ResultSetHandler<T>{
101     // 保存传入的要封装的类的字节码
102     private Class<T> clazz;
103     public BeanHandler(Class<T> clazz) {
104         this.clazz = clazz;
105     }
106     
107     // 封装结果集的方法
108     @Override
109     public T handle(ResultSet rs) throws SQLException {
110         try {
111             // 创建要封装的对象  ‘1’
112             T t = clazz.newInstance(); 
113             // 向下读一行
114             if (rs.next()) {
115                 
116                 // a. 获取类的所有的Field字段数组
117                 Field[] fs = clazz.getDeclaredFields();
118                 
119                 // b. 遍历, 得到每一个字段类型:Field
120                 for (Field f : fs) {
121                 
122                     // c. 获取”属性名称“
123                     String fieldName = f.getName();
124                     
125                     // e. 获取Field字段上注解   【@Column(columnName = "a_userName")】
126                     Column column =  f.getAnnotation(Column.class);
127                     
128                     // f. ”字段名“
129                     String columnName = column.columnName();        // 数据库中字段 a_userName
130                     
131                     // g. 字段值
132                     Object columnValue = rs.getObject(columnName);
133                     
134                     // 设置(BeanUtils组件)
135                     BeanUtils.copyProperty(t, fieldName, columnValue);
136                 }
137             }
138             return t;
139         } catch (Exception e) {
140             throw new RuntimeException(e);
141         }
142     }
143 }
144 
145 
146 /**
147  * 自定义结果集:封装多个Bean对象到List集合
148  */
149 class BeanListHandler<T> implements ResultSetHandler<List<T>>{
150     
151     // 要封装的单个对象
152     private Class<T> clazz;
153     public BeanListHandler(Class<T> clazz){
154         this.clazz = clazz;
155     }
156 
157     // 把从数据库查询到的没一行记录,封装为一个对象,再提交到list集合, 返回List<T>
158     @Override
159     public List<T> handle(ResultSet rs) throws SQLException {
160         List<T> list = new ArrayList<T>();
161         try {
162             // 向下读一行
163             while (rs.next()) {
164                 
165                 // 创建要封装的对象  ‘1’
166                 T t = clazz.newInstance(); 
167                 
168                 // a. 获取类的所有的Field字段数组
169                 Field[] fs = clazz.getDeclaredFields();
170                 
171                 // b. 遍历, 得到每一个字段类型:Field
172                 for (Field f : fs) {
173                 
174                     // c. 获取”属性名称“
175                     String fieldName = f.getName();
176                     
177                     // e. 获取Field字段上注解   【@Column(columnName = "a_userName")】
178                     Column column =  f.getAnnotation(Column.class);
179                     
180                     // f. ”字段名“
181                     String columnName = column.columnName();        // 数据库中字段 a_userName
182                     
183                     // g. 字段值
184                     Object columnValue = rs.getObject(columnName);
185                     
186                     // 设置(BeanUtils组件)
187                     BeanUtils.copyProperty(t, fieldName, columnValue);
188                 }
189                 // 对象添加到集合
190                 list.add(t);
191             }
192             return list;
193         } catch (Exception e) {
194             throw new RuntimeException(e);
195         }
196     }
197     
198 }

 

posted on 2015-10-22 19:13  想飞的程序员  阅读(211)  评论(0编辑  收藏  举报