什么是注解
《think in java》中是这样解释的——注解(也被称为元数据)为我们在代码中添加信息提供一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据
注解有什么用处
通过配合反射可以让我们很方便的获取类内的信息 起到标识的作用
java中内置了三种标准注解:
@Override,表示当前定义将覆盖超类中的方法
@Deprecated 用来标识过时的方法
@SupperssWarnings 关闭不当的编译器警告信息
四种元注解 元注解用来负责注解其他的注解
@Targert 标识 注解可以用与什么地方 (类,方法....)
@Retention 标识什么级别的保存该注解信息
@Documented 生成java中
@Inherited 允许子类继承父类的注解
注解元素可用的类型
所有的基本类型
String
Class
enum
Annotation
以上类型的数组
一个使用注解的例子
类注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {
String value();
}
方法注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Column {
String value();
int length()default 200;
}
使用注解的类
@Table
public class Supper {
private Integer id; //主键
private String title;//标题
private String text;//正文
private String time;//日期
private String url;//地址
private Integer view;//查看量
private String author;//作者
private String tag;//标签
@Id
public Integer getId() {
return id;
}
/**
*
* @param id 主键
*/
public void setId(Integer id) {
this.id = id;
}
@Column("title")
public String getTitle() {
return title;
}
/**
*
* @param title 标题
*/
public void setTitle(String title) {
this.title = title;
}
@Column(value="text",length=20000)
public String getText() {
return text;
}
/**
*
* @param text 正文
*/
public void setText(String text) {
this.text = text;
}
@Column("time")
public String getTime() {
return time;
}
/**
*
* @param time 日期
*/
public void setTime(String time) {
this.time = time;
}
@Column("url")
public String getUrl() {
return url;
}
/**
*
* @param url 地址
*/
public void setUrl(String url) {
this.url = url;
}
@Column("view")
public Integer getView() {
return view;
}
/**
*
* @param view 查看量
*/
public void setView(Integer view) {
this.view = view;
}
@Column("author")
public String getAuthor() {
return author;
}
/**
*
* @param author 作者
*/
public void setAuthor(String author) {
this.author = author;
}
@Column("tag")
public String getTag() {
return tag;
}
/**
*
* @param tag 标签
*/
public void setTag(String tag) {
this.tag = tag;
}
}
使用注解通过反射生成sql语句
public class SqlFactory {
/**
* text字段会出现问题
* @param obj
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static String save(Object obj) {
StringBuilder sql = new StringBuilder();
StringBuilder sqlValue = new StringBuilder();
try {
Class c = obj.getClass();
boolean tFlag = c.isAnnotationPresent(Table.class);
if (tFlag) {
// 得到表名
Table tables = (Table) c.getAnnotation(Table.class);
sqlValue.append("values(");
String table = tables.value();
sql.append("insert into " + table + "(");
Method[] methods = c.getMethods();
for (Method method : methods) {
// 得到字段
tFlag = method.isAnnotationPresent(Column.class);
if (tFlag) {
Column colum = (Column) method.getAnnotation(Column.class);
String columName = colum.value();// 得到字段名
// 得到方法名
String mStr = method.getName();
// 得到方法
Method m = c.getMethod(mStr);
Object columValue = m.invoke(obj);// 得到字段值
if (columValue != null) {
sql.append(columName + ",");
if (columValue instanceof String) {
sqlValue.append("'" + columValue + "',");
} else if (columValue instanceof Integer) {
sqlValue.append(columValue + ",");
}
}
}
}
sql.delete(sql.length() - 1, sql.length());
sqlValue.delete(sqlValue.length() - 1, sqlValue.length());
sqlValue.append(")");
sql.append(") " + sqlValue);
System.out.println(sql);
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return sql.toString();
}
/**
*
* @param obj
* @return 生成建表语句
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static String createTable(Object obj) {
StringBuilder sql = new StringBuilder();
Class c = obj.getClass();
if (c.isAnnotationPresent(Table.class)) {
Table table = (Table) c.getAnnotation(Table.class);
sql.append("Create table " + table.value() + "(");
Method[] m = c.getMethods();//
for (Method method : m) {
boolean flag = method.isAnnotationPresent(Column.class);
if (flag) {
Column column = (Column) method.getAnnotation(Column.class);
if (method.getReturnType().getSimpleName().equals("String")) {
sql.append(column.value() + " varchar(" + column.length() + "),");
}else if (method.getReturnType().getSimpleName().equals("Integer") ) {
sql.append(column.value() + " Integer NOT NULL DEFAULT 0 ,");
}
}
boolean flagId = method.isAnnotationPresent(Id.class);
if(flagId){
Id id = (Id)method.getAnnotation(Id.class);
sql.append(id.value()+" Integer auto_increment , PRIMARY KEY ( "+id.value()+" ),");
}
}
}
sql.delete(sql.length()-1, sql.length());
sql.append(")");
return sql.toString();
}
/**
*
* 因为text无法被数据库保存 改为拼装 ? 问题解决
* sql = "insert into ifanr (text) values(?)";
* PreparedStatement ps = conn.prepareStatement(sql);
* ps.setString(1, supper.getText());
* ps.executeUpdate();
*
* @param obj
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static String savePuls(Object obj) {
StringBuilder sql = new StringBuilder();
StringBuilder sqlValue = new StringBuilder();
try {
Class c = obj.getClass();
boolean tFlag = c.isAnnotationPresent(Table.class);
if (tFlag) {
// 得到表名
Table tables = (Table) c.getAnnotation(Table.class);
sqlValue.append("values(");
String table = tables.value();
sql.append("insert into " + table + "(");
Method[] methods = c.getMethods();
for (Method method : methods) {
// 得到字段
tFlag = method.isAnnotationPresent(Column.class);
if (tFlag) {
Column colum = (Column) method.getAnnotation(Column.class);
String columName = colum.value();// 得到字段名
// 得到方法名
String mStr = method.getName();
// 得到方法
Method m = c.getMethod(mStr);
Object columValue = m.invoke(obj);// 得到字段值
if (columValue != null) {
sql.append(columName + ",");
if(columName.equals("text")){
sqlValue.append("? ,");
}else if (columValue instanceof String) {
sqlValue.append("'" + columValue + "',");
} else if (columValue instanceof Integer) {
sqlValue.append(columValue + ",");
}
}
}
}
sql.delete(sql.length() - 1, sql.length());
sqlValue.delete(sqlValue.length() - 1, sqlValue.length());
sqlValue.append(")");
sql.append(") " + sqlValue);
}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
return sql.toString();
}
/**
* 用来查询最后一条记录
* @param obj
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static String findByColumDesc(Object obj ,String colum,int num){
Class c = obj.getClass();
StringBuilder sql = new StringBuilder();
boolean falg = c.isAnnotationPresent(Table.class);
if(falg){
sql.append("select "+colum+" from ");
Table table = (Table)c.getAnnotation(Table.class);
sql.append(table.value());
sql.append(" order by id DESC limit "+num+",1");
}
return sql.toString();
}
}
还有其他部分代码就不再贴 了
总结:
使用注解可以使我们的代码与说明或配置更好的结合在一其 比起 java类与xml文件的分离 编写起来更友好
当注解配合反射使用时效果会更加明显如果加与动态代理可以时我们的代码拥有更换的灵活性及可扩展性
但也并不是完全取代了xml 在结构逻辑比较复杂的时候xml的效果会跟好一些 比如 spring中的事务使用注解 并没有xml配置的通用性好
好的工具会让我们的生产力得到更大的提升与发挥 编程语言只是一种有利的工具