Java中自定义注解的应用

时间:2021-05-01 05:47:47

来自 慕课网 的学习

       我们可以使用自定义注解,实现ORM,即对象/关系的映射。通过自定义注解,定义对象对应数据表的属性,如表名,表字段等。

       Table.java(Table注解)

package com.ann.demo;

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)
public @interface Table {
	String value();
}
        Column.java (Column注解)

package com.ann.demo;

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)
public @interface Column {
	String value();
}
       Filter.java(使用到Table和Column注解,定义该类对应的数据表和数据表的字段)
package com.ann.demo;

@Table("user")
public class Filter {
	
	@Column("id")
	private int id;
	
	@Column("user_name")
	private String username;
	
	@Column("nickname")
	private String nickname;
	
	@Column("age")
	private int age;
	
	@Column("city")
	private String city;
	
	@Column("email")
	private String email;
	
	@Column("mobile")
	private String mobile;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
}

       Filter2.java

package com.ann.demo;

@Table("department")
public class Filter2 {
	
	@Column("id")
	private int id;
	
	@Column("name")
	private String name;
	
	@Column("leader")
	private String leader;
	
	@Column("amount")
	private int amount;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getLeader() {
		return leader;
	}

	public void setLeader(String leader) {
		this.leader = leader;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}
}

       Test.java(解析类和属性上的注解,可以得到对应数据库上表名和字段名,并进行相应操作)

package com.ann.demo;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
	public static void main(String[] args) {
		Filter f1 = new Filter();
		f1.setId(10); //查询id为10的用户
		
		Filter f2 = new Filter();
		f2.setUsername("lucy"); //查询用户名为lucy的用户
		f2.setAge(18);
		
		Filter f3 = new Filter();
		f3.setEmail("liu@sina.com, zh@163.com, 77777@qq.com"); //查询邮箱为其中任意一个的用户
		
		String sql1 = query(f1);
		String sql2 = query(f2);
		String sql3 = query(f3);
		
		System.out.println(sql1);
		System.out.println(sql2);
		System.out.println(sql3);
		
		
		Filter2 filter2 = new Filter2();
		filter2.setAmount(10);
		filter2.setName("技术部");
		System.out.println(query(filter2));
		
	}
	
	private static String query(Object f) {
		StringBuilder sb = new StringBuilder();
		//1.获取到class
		Class c = f.getClass();
		
		//2.获取到table的名字
		boolean exists = c.isAnnotationPresent(Table.class);
		if(!exists) {
			return null;
		}
		Table t = (Table)c.getAnnotation(Table.class);
		String tableName = t.value();
		
		sb.append("select * from ").append(tableName).append(" where 1 = 1");
		//3.遍历所有字段
		Field[] fArray = c.getDeclaredFields();
		for(Field field : fArray) {
			//4.处理每个字段对应的sql
			//4.1 拿到字段名
			boolean fExists = field.isAnnotationPresent(Column.class);
			if(!fExists) {
				continue;
			}
			Column column = field.getAnnotation(Column.class);
			String columnName = column.value();
			//4.2 拿到字段的值
			String fieldName = field.getName();
			String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			Object fieldValue = null;
			try {
				Method getMethod = c.getMethod(getMethodName);
				
				fieldValue = getMethod.invoke(f);
				
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (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();
			}
			
			//4.3 拼装sql
			if(fieldValue == null || ((fieldValue instanceof Integer) && (Integer)fieldValue == 0)) {
				continue;
			}
			
			sb.append(" and ").append(columnName);
			if(fieldValue instanceof String) {
				if(((String)fieldValue).contains(",")) {
					String[] values = ((String)fieldValue).split(",");
					sb.append(" in(");
					for(String v : values) {
						sb.append("'").append(v.trim()).append("'").append(",");
					}
					sb.deleteCharAt(sb.length() - 1);
					sb.append(")");
				} else {
					sb.append("=").append("'").append(fieldValue).append("'");					
				}
				
			} else if(fieldValue instanceof Integer) {
				sb.append("=").append(fieldValue);
			}
			
		}
		
		return sb.toString();
	}
}

       运行结果如下:

Java中自定义注解的应用