概述
注解与注释,
注解,告诉编译器如何运行程序!
注释,给程序员阅读,对编译、运行没有影响;
注解作用,
1.告诉编译器如何运行程序;
2.简化(取代)配置文件
常用的注解如下:
//重写父类的方法 @Override public String toString() { returnsuper.toString(); }
//抑制编译器警告 @SuppressWarnings({"unused","unchecked"}) privatevoid save() { List list =null; }
//标记方法以及过时 @Deprecated privatevoid } |
元注解:表示注解的注解
指定注解的可用范围:
@Target({
TYPE, 类
FIELD, 字段
METHOD, 方法
PARAMETER, 参数
CONSTRUCTOR,构造器
LOCAL_VARIABLE 局部变量
})
元注解 - 2.指定注解的声明周期
@Retention(RetentionPolicy.SOURCE) 注解只在源码级别有效
@Retention(RetentionPolicy.CLASS) 注解在字节码即别有效 默认值
@Retention(RetentionPolicy.RUNTIME) 注解在运行时期有效
注解案例之优化BaseDao的代码
一、创建Bean实体类
package cn.sp.utils;
@Table(tableName="admin")
public class Admin2 {
@ID
@Column(columnName="id")
private int id2;
@Column(columnName="userName")
private String userName2;
@Column(columnName="pwd")
private String pwd2;
public int getId2() {
return id2;
}
public void setId2(int id2) {
this.id2 = id2;
}
public String getUserName2() {
return userName2;
}
public void setUserName2(String userName2) {
this.userName2 = userName2;
}
public String getPwd2() {
return pwd2;
}
public void setPwd2(String pwd2) {
this.pwd2 = pwd2;
}
@Override
public String toString() {
return "Admin2 [id2=" + id2 + ", userName2=" + userName2 + ", pwd2=" + pwd2 + "]";
}
}
二、创建注解类
package cn.sp.utils;
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 cn.sp.dao.JdbcUtil;
public class BaseDao_2 <T>{
private Class<T> clazz;
private String tableName;
private String id_primary;
public BaseDao_2() {
Type type=this.getClass().getGenericSuperclass();
ParameterizedType pt=(ParameterizedType) type;
Type[] types = pt.getActualTypeArguments();
clazz=(Class<T>) types[0];
/*******获取表名******/
Table table = clazz.getAnnotation(Table.class);
tableName = table.tableName();
//已经拿到Admin2.class
//获取当前运行类的所有字段,遍历。获取每一个字段上的id注解
Field[] fs = clazz.getDeclaredFields();
for (Field field : fs) {
//设置强制访问
field.setAccessible(true);
//获取每一个字段上的ID注解
ID anno_id = field.getAnnotation(ID.class);
//判断
if(anno_id!=null){
//如果当前字段有ID注解,说明是主键,再获取字段名称
Column column = field.getAnnotation(Column.class);
//主键
id_primary=column.columnName();
break;
}
}
System.out.println("表:"+tableName);
System.out.println("主键:"+id_primary);
}
public T findById(int id){
try {
String sql="select * from "+tableName+" where id=?";
return JdbcUtil.getQueryRunner().query(sql, new MyBeanHandler<T>(clazz),id);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public List<T> getAll(){
try {
String sql="select * from "+tableName;
return JdbcUtil.getQueryRunner().query(sql, new MyBeanListHandler<T>(clazz));
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
/**
* 自定义结果集封装单个Bean对象
*/
class MyBeanHandler<T> implements ResultSetHandler<T>{
private Class<T> clazz;
public MyBeanHandler(Class<T> clazz) {
this.clazz=clazz;
}
@Override
public T handle(ResultSet rs) throws SQLException {
try {
T t=clazz.newInstance();
if(rs.next()){
Field[] fs = clazz.getDeclaredFields();
for (Field f : fs) {
String fieldName=f.getName();
Column column = f.getAnnotation(Column.class);
String columnName=column.columnName();
Object columnValue=rs.getObject(columnName);
//设置 BeanUtils组件
BeanUtils.copyProperty(t, fieldName, columnValue);
}
}
return t;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**自定义结果集封装多个Bean对象
*/
class MyBeanListHandler<T> implements ResultSetHandler<List<T>>{
private Class<T> clazz;
public MyBeanListHandler(Class<T> clazz) {
this.clazz=clazz;
}
public List<T> handle(ResultSet rs) throws SQLException {
ArrayList<T> list = new ArrayList<T>();
try {
while(rs.next()){
T t=clazz.newInstance();
Field[] fs = clazz.getDeclaredFields();
for (Field f : fs) {
String fieldName=f.getName();
Column column = f.getAnnotation(Column.class);
String columnName=column.columnName();
Object columnValue=rs.getObject(columnName);
//设置 BeanUtils组件
BeanUtils.copyProperty(t, fieldName, columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
创建类AdminDao2(用于测试执行)
package cn.sp.utils;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
public class AdminDao2 extends BaseDao_2<Admin2> {
@Test
public void testName() throws Exception {
AdminDao2 dao2 = new AdminDao2();
Admin2 ad2 = dao2.findById(1);
List<Admin2> list = dao2.getAll();
System.out.println(ad2);
System.out.println(list);
}
}
相关注解代码:
package cn.sp.utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* 用于描述主键
* @author Administrator
*
*/
@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时期有效
public @interface ID {
}
package cn.sp.utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时期有效
public @interface Table {
String tableName();
}
package cn.sp.utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时期有效
public @interface Column {
String columnName();
}
注意:一定要在注解上加元注解@Retention(RetentionPolicy.RUNTIME),否则运行时注解失效,会报空指针异常!
package cn.sp.utils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) // 指定注解在运行时期有效
public @interface Column {
String columnName();
}