java注解全面解析--实例
使用注解封装自动拼接sql
1、定义注解类
TableName: 用来注解 表名 ,拥有一个属性 value
将适用范围定为:TYPE Class, interface enum 范围可用
作用时间定为:RetentionPolicy.RUNTIME(运行时存在)
fields: 用来注解表字段名,拥有一个属性 value
将适用范围定为:FIELD 范围可用
作用时间定为:RetentionPolicy.RUNTIME(运行时存在)
2、创建实体类
user类:
在类定义上方使用注解TableName,注解表名
在类属性上方使用注解fields,注解字段名
3、创建工具类
SqlUtil:
定义函数:spliceSql(User user)
有必要可以将参数改为:Object object 将这个方法适配所有类
实现思路:
1、使用 stringBuilder 拼接sql ,没涉及到线程所以这里不用stringbuffer也可以
StringBuilder sBuilder = new StringBuilder("select * from ");
2、使用反射判断该类是否使用了 tameName 注解表名,若没有使用注解则return null
2.1、得到class对象(类对象)
Class c = user.getClass();
2.2、判断是否使用注解
boolean isuseTableName = c.isAnnotationPresent(TableName.class);
3、得到该类的左右属性,然后判断属性是否使用注解:Fields 注解表字段名。没有使用则继续循环
3.1、得类类属性数组
Field[] files = c.getDeclaredFields();
3.2、在for循环当中对每一个属性进行以下操作:
3.3.1:判断是否使用注解,没有使用则进行下一次循环
3.3.2:得到字段名:获取注解值
Fields fields = field.getAnnotation(Fields.class);//拿到注解类 Fields
String columnName = fields.value();//拿到value值
3.3.3:拼出类属性的get方法:get + 首字母大写。拿到值
String getMethodName = "get" + parmentName.substring(0,1).toUpperCase() + ""+parmentName.substring(1);
//使用反射调用方法
Method method = c.getMethod(getMethodName);
filedValue = method.invoke(user);
3.3.4:判断类属性类型,拼接sql需要区分字符和数值类型。sql写法不一致拼接完成后返回sql。
4、代码:
/**
* 拼接sql文,并返回sql字符串
* @param user
* @return
*/
public String spliceSql(User user) {
//拼接sql
StringBuilder sBuilder = new StringBuilder("select * from ");
@SuppressWarnings("rawtypes")
Class c = user.getClass();
//得到表名
//判断是否使用了table注解
@SuppressWarnings("unchecked")
boolean isuseTableName = c.isAnnotationPresent(TableName.class);
if (false == isuseTableName ) {
return "没有注解表名";
}
if (isuseTableName) {
TableName tableName = user.getClass().getAnnotation(TableName.class);
sBuilder.append(tableName.value());
sBuilder.append(" where 1=1 ");
}
//得到类属性的所有字段
Field[] files = c.getDeclaredFields();
for (Field field : files) {
//判断是否使用Fields注解字段名
if (!field.isAnnotationPresent(Fields.class)) {
continue;
};
//得到属性上注解的字段名
Fields fields = field.getAnnotation(Fields.class);
String columnName = fields.value();
//得到属性名
String parmentName = field.getName();
//得到相应的get方法 get + 属性名首字母大写
String getMethodName = "get" + parmentName.substring(0,1).toUpperCase() + ""+parmentName.substring(1);
//得到检索条件值 拼接sql
Object filedValue = "";
try {
//调用方法
@SuppressWarnings("unchecked")
Method method = c.getMethod(getMethodName);
filedValue = method.invoke(user);
if ("".equals(filedValue) ||( filedValue instanceof Integer && (Integer)filedValue==0)) {
continue;
}
//拼接sql
//判断字段数据类型
if (filedValue instanceof String) {
sBuilder.append("and "+columnName+"="+ "'" + filedValue+ "' ");
}
if (filedValue instanceof Integer) {
sBuilder.append("and "+columnName+"="+filedValue+" ");
}
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sBuilder.toString();
}