文章目录
注解
告诉编译器如何运行程序并简化配置文件
基本的Annotation
Depercated:用于表示某个程序元素(类, 方法等)已过时
Override:限定重写父类方法, 该注解只能用于方法
SuppressWarnings: 抑制编译器警告
Target:应用注解的项
Retention:注解的生命周期
自定义注解
定义新的 Annotation 类型使用 @interface 关键字
声明注解的属性
注解属性的作用:原来写在配置文件中的信息,可以通过注解的属性进行描述。
Annotation 的属性声明方式:String name()或String[] likes();
属性默认值声明方式:String name() default “xxx”;
特殊属性value:如果注解中有一个名称value的属性,那么使用注解时可以省略value=部分,[email protected](“xxx”)
特殊属性value[];
枚举值之间使用逗号分隔1
2
3
4
5
6
7
8
9
10
11@MyAnnotation(name="jack",age=30,likes={"唱歌","跳舞"})
@Author(name = "yujie", value = { "hehe","哈哈","嗯嗯" })
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String ();
int age() default 30;
String[] value();
}
元注解
1.Target
元注解可以应用一个注解,以限制该注解可以应用到哪些项
ElementType.TYPE类及其接口 ElementType.METHOD方法 ElementType.FIELD成员域 ElementType.PARAMETER方法或构造参数
ElementType.LOCAL_VARIABLE局部变量
2.Retention
指定一条注解的保留时间
RetentionPolicy.CLASS字节码有效 RetentionPolicy.SOURCE源码有效 RetentionPolicy.RUNTIME运行时有效(作用范围最大)
反射的封装
满足的条件:表名和对象名一致 表中的字段和对象的属性名称相同1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40public class BaseDao{
private Class clazz;
private String tablename;
public BaseDao(){
Type type = this.getClass().getGenericSuperclass(); //得到当前运行类的父类
//强制转为参数化类型
ParameterizedType ptype=(ParameterizedType)type;
//得到参数化类型的时间定义
Type[] atype = ptype.getActualTypeArguments();
clazz=(Class) atype[0];
tablename=clazz.getSimpleName(); //得到表名
}
public T getbyid(int id){
String sql="select *from "+tablename+" where id=?";
try {
returnnew Jdbc().getQueryRunner().query(sql, new BeanHandler(clazz), id);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public List getAllbyid(){
String sql = "select * from " + tablename ;
try {
return new Jdbc().getQueryRunner().query(sql, new BeanListHandler(clazz));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
利用注解的改进后的反射封装
满足:表名不必和对象名一致
表的字段和对象的属性名不一致
ID不一定为主键
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202public class BaseDao{
private Class clazz;
private String tablename;
private String ID; //主键
public BaseDao(){
Type type = this.getClass().getGenericSuperclass();
ParameterizedType ptype=(ParameterizedType) type;
Type[] atype = ptype.getActualTypeArguments();
clazz=(Class) atype[0];
//1.获取表名
Table table=clazz.getAnnotation(Table.class);
tablename=table.tablename(); //拿到表名
//2.获取主键
//获取当前运行类的所有字段。遍历 获取每个字段上的ID注解
Field[] fields = clazz.getDeclaredFields();
for(Field f:fields){
f.setAccessible(true);
//获取每个字段的ID注解
ID id = f.getAnnotation(ID.class);
if(id!=null){
columnName cname= f.getAnnotation(columnName.class); //为主键
ID=cname.columnname(); //得到主键
break;
}
}
}
public T getbyid(int id){
try {
String sql="select * from"+tablename+"where"+ID+"=?";
return jdbc.getQueryRunner.query(sql,new myBeanhandler(clazz),id); //不可用 需要自定义结果集
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public List getAll(){
try {
String sql="select * from"+tablename;
return jdbc.getQueryRunner.query(sql,new myBeanListHandler(clazz)); //不可用 需要自定义结果集
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
因为Dbutils中的new BeanListHandler new BeanHandler必须满足字段名和对象属性名一致才能封装,所以要自定义结果集
//自定义结果集 封装bean对象
class myBeanhandler{
//
private Class clazz;
public myBeanhandler(Class clazz){
this.clazz=clazz;
}
public T handler(ResultSet rs) throws Exception{
//创建要封装的对象
T t=clazz.newInstance();
if(rs.next()){
//获取类的所有的字段的数组
Field[] field = clazz.getDeclaredFields();
//拿到字段类型
for(Field f:field){
//拿到属性名称
String fieldName=f.getName();//例 student对象中的sid sname
columnName cname=f.getAnnotation( columnName.class);
String sname=cname.columnname();//拿到属性上的注解名 即数据库中的额名称
Object svalue=rs.getObject(sname);
//封装对象 BeanUtils
BeanUtils.copyProperty(t, fieldName, svalue);
}
}
return t;
}
}
//自定义封装多个bean到list对象中
class myBeanListHandler implements ResultSetHandler>{
private Class clazz;
public myBeanListHandler(Class clazz){
}
@Override
public List handle(ResultSet rs) throws SQLException{
//创建要封装的对象
List list=new ArrayList();
while(rs.next()){
T t=clazz.newInstance();
//获取类的所有的字段的数组
Field[] field = clazz.getDeclaredFields();
//拿到字段类型
for(Field f:field){
//拿到属性名称
String fieldName=f.getName();//例 student对象中的sid sname
columnName cname=f.getAnnotation( columnName.class);
String sname=cname.columnname();//拿到属性上的注解名 即数据库中的额名称
Object svalue=rs.getObject(sname);
//封装对象 BeanUtils
BeanUtils.copyProperty(t, fieldName, svalue);
}
list.add(t);
}
return list;
}
}
}
student类
@Table(tablename="student") //对应数据库表名
public class Student{
@ID
@columnName(columnname="id") //对应数据库中的值
private int sid;
@columnName(columnname="name")
private String sname;
public Student(int sid, String sname){
this.sid = sid;
this.sname = sname;
}
public Student(){
// TODO Auto-generated constructor stub
}
public int getSid(){
return sid;
}
public void setSid(int sid){
this.sid = sid;
}
public String getSname(){
return sname;
}
public void setSname(String sname){
this.sname = sname;
}
}
注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String tablename();
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface columnName {
String columnname();
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ID {
}