如何创建、使用以及解析自定义注解

来源:互联网 发布:ubuntu停止当前命令 编辑:程序博客网 时间:2024/05/16 08:00

首先要想使用自定义注解,必须创建自己的注解类

右键项目,new -> Annotation

然后在注解里定义自己的方法,该方法是别的类使用注解时需要填的属性

package com.sy.demo.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Table {    public String value();}
注:如果只有一个方法时,应该用value()来指定方法名,这样就可以直接简写@Table("xxx")而不是@Table(aaa="xxx");

其中注解类上的注解称为元注解

@Target(ElementType.TYPE)
@Target的意思是,该注解类是放在什么位置的,是放在类上、字段上还是方法上,ElementType.TYPE意思是只能放在类上或接口上,ElementType.FIELD意思是只能放在字段上等等。

如果有多个位置选择可以这么写:

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)
意思是作用域,一般写RUNTIME就行


@Documented
意思是是否在生成JavaDoc时加入该注解类,这个看情况写不写

还有其他元注解,想要研究的就自己研究吧


定义完自定义注解了,下面就是使用的时候了


package com.sy.demo.entity;import com.sy.demo.annotation.Column;import com.sy.demo.annotation.Table;@Table("tdb_user")public class User {@Column("id")private Long id;@Column("email")private String email;@Column("password")private String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

在这里我定义了一个实体类,用于表示用户信息,其中还是用了一个@Column类,代码如下

package com.sy.demo.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Column {public String value();}
由代码可知,@Column是放在field上的


使用也使用完了,下面该是解析的时候了。

package com.sy.demo.util;import java.lang.reflect.Field;import com.sy.demo.annotation.Column;import com.sy.demo.annotation.Table;public class SqlUtil {private static final String EMPTY = "";@SuppressWarnings("unchecked")public static String getSql(Object object) {StringBuilder sb = new StringBuilder();Class<Object> c;boolean isExist;Column column;String columnName;String getMethodName;Object columnValue;String[] strs;try {c = (Class<Object>) object.getClass();isExist = c.isAnnotationPresent(Table.class);if (!isExist) {return EMPTY;}Table table = c.getAnnotation(Table.class);sb.append(" SELECT * FROM " + table.value() + " WHERE 1 = 1 " );Field[] fields = c.getDeclaredFields();for (Field field: fields) {isExist = field.isAnnotationPresent(Column.class);if (!isExist) {continue;}column = field.getAnnotation(Column.class);columnName = column.value();getMethodName = "get" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);columnValue = c.getMethod(getMethodName, new Class[0]).invoke(object, new Object[0]);if (columnValue == null) {continue;}if (columnValue instanceof String) {columnValue = (String)columnValue;if(((String) columnValue).contains(",")) {sb.append("AND " + columnName + " IN (");strs = ((String) columnValue).split(",");for(String str: strs) {sb.append("'" + str + "',");}sb.deleteCharAt(sb.length() - 1);sb.append(") ");} else {sb.append("AND " + columnName + " = '" + columnValue + "' ");}} else if (columnValue instanceof Integer || columnValue instanceof Long) {sb.append("AND " + columnName + " = " + columnValue + " ");} }} catch (Exception e) {e.printStackTrace();}return sb.toString();}}

解析的时候用的是反射机制,可能看着比较麻烦比较乱,而且也新手可能也不太理解,在用的时候会发现其实还是挺方便的。

原理解释根据反射找到User类,在判断是否有注解,接着拼接sql什么的


整个列子项目中完整的代码如下(有许多步骤测试用例,懒得删了,全贴出来吧)

Controller

package com.sy.demo.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.sy.demo.entity.User;import com.sy.demo.service.IUserService;@Controller@RequestMapping("hello")public class UserController {@Autowiredprivate IUserService hService;@RequestMapping(value = "demo1")public String demo1() {return "demo1";}@SuppressWarnings("deprecation")@RequestMapping(value = "demo2")public String demo2() {return hService.test();}@RequestMapping(value = "demo3")@ResponseBodypublic String demo3() {User user = new User();user.setId(1L);user.setEmail("mr_songyang1990@163.com");user.setPassword("1q2w3e4r,123456,aaaaa");return hService.getUser(user);}@RequestMapping(value = "demo4")@ResponseBodypublic String demo4() {User user = new User();user.setId(1L);user.setEmail("mr_songyang1990@163.com");user.setPassword("1q2w3e4r,123456,aaaaa");return hService.getUser2(user);}}

service:

package com.sy.demo.service;import com.sy.demo.entity.User;public interface IUserService {@Deprecatedpublic String test();public String getUser(User user);public String getUser2(User user);}

package com.sy.demo.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.sy.demo.entity.User;import com.sy.demo.repository.IUserRepository;import com.sy.demo.service.IUserService;@Service("hService")public class UserServiceImpl implements IUserService {@Autowiredprivate IUserRepository hRepository;@Deprecated@Overridepublic String test() {return "demo2";}@Overridepublic String getUser(User user) {return hRepository.queryUser(user);}@Overridepublic String getUser2(User user) {return hRepository.queryUser2(user);}}

Repository

package com.sy.demo.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.sy.demo.entity.User;import com.sy.demo.repository.IUserRepository;import com.sy.demo.service.IUserService;@Service("hService")public class UserServiceImpl implements IUserService {@Autowiredprivate IUserRepository hRepository;@Deprecated@Overridepublic String test() {return "demo2";}@Overridepublic String getUser(User user) {return hRepository.queryUser(user);}@Overridepublic String getUser2(User user) {return hRepository.queryUser2(user);}}

package com.sy.demo.repository.impl;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.springframework.stereotype.Repository;import com.sy.demo.entity.User;import com.sy.demo.repository.IUserRepository;import com.sy.demo.util.DBUtil;import com.sy.demo.util.SqlUtil;@Repository("hRepository")public class UserRepositoryImpl implements IUserRepository {public String queryUser(User user) {String sql = SqlUtil.getSql(user);System.out.println(sql);return sql;}@Overridepublic String queryUser2(User user) {StringBuilder sb = new StringBuilder();String sql = SqlUtil.getSql(user);System.out.println(sql);PreparedStatement ps = DBUtil.getPreparedStatement(sql);Long id;String email;String password;try {ResultSet rs = ps.executeQuery();while (rs.next()) {id = rs.getLong("id");email = rs.getString("email");password = rs.getString("password");sb.append("ID:").append(id).append(", email:").append(email).append(", password:").append(password).append("<br/>");}} catch (SQLException e) {e.printStackTrace();}return sb.toString();}}

entity:

package com.sy.demo.entity;import com.sy.demo.annotation.Column;import com.sy.demo.annotation.Table;@Table("tdb_user")public class User {@Column("id")private Long id;@Column("email")private String email;@Column("password")private String password;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

annotation

package com.sy.demo.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Table {public String value();}

package com.sy.demo.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Column {public String value();}

util工具类

package com.sy.demo.util;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;public class DBUtil {public static final String URL = "jdbc:mysql://localhost:3306/db_test";public static final String USERNAME = "root";public static final String PASSWORD = "root";public static Connection conn = null;public static MysqlDataSource dataSource;static {dataSource = new MysqlDataSource();dataSource.setUser(USERNAME);dataSource.setPassword(PASSWORD);dataSource.setURL(URL);}public static PreparedStatement getPreparedStatement(String sql) {try {conn = dataSource.getConnection();return conn.prepareStatement(sql);} catch (SQLException e) {e.printStackTrace();}return null;}}

package com.sy.demo.util;import java.lang.reflect.Field;import com.sy.demo.annotation.Column;import com.sy.demo.annotation.Table;public class SqlUtil {private static final String EMPTY = "";@SuppressWarnings("unchecked")public static String getSql(Object object) {StringBuilder sb = new StringBuilder();Class<Object> c;boolean isExist;Column column;String columnName;String getMethodName;Object columnValue;String[] strs;try {c = (Class<Object>) object.getClass();isExist = c.isAnnotationPresent(Table.class);if (!isExist) {return EMPTY;}Table table = c.getAnnotation(Table.class);sb.append(" SELECT * FROM " + table.value() + " WHERE 1 = 1 " );Field[] fields = c.getDeclaredFields();for (Field field: fields) {isExist = field.isAnnotationPresent(Column.class);if (!isExist) {continue;}column = field.getAnnotation(Column.class);columnName = column.value();getMethodName = "get" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);columnValue = c.getMethod(getMethodName, new Class[0]).invoke(object, new Object[0]);if (columnValue == null) {continue;}if (columnValue instanceof String) {columnValue = (String)columnValue;if(((String) columnValue).contains(",")) {sb.append("AND " + columnName + " IN (");strs = ((String) columnValue).split(",");for(String str: strs) {sb.append("'" + str + "',");}sb.deleteCharAt(sb.length() - 1);sb.append(") ");} else {sb.append("AND " + columnName + " = '" + columnValue + "' ");}} else if (columnValue instanceof Integer || columnValue instanceof Long) {sb.append("AND " + columnName + " = " + columnValue + " ");} }} catch (Exception e) {e.printStackTrace();}return sb.toString();}}

完整例子程序下载地址:http://download.csdn.net/detail/csdn_mrsongyang/8928827


参考资料:http://www.imooc.com/learn/456


0 0
原创粉丝点击