Java注解简介、自定义注解及模拟Junit、模拟hibernate根据实体类建表

Java注解简介、自定义注解及模拟Junit、模拟hibernate根据实体类建表

  • 注解简介
    • Java SE5 三个内置标准注解
    • 元注解:
  • 自定义注解
  • Java注解模拟实现Junit
  • 注解模拟Hibernate中根据实体类在数据库建表的方法

注解简介

注解:JDK1.5的新特性

注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。

Java SE5 三个内置标准注解

  • @Override:方法覆盖、重写;
  • @Deprecated:过时的;
  • @SupperessWornings:关闭不当的编译器警告信息;

元注解:

  • @Target:表示注解在什么地方使用,可用ElementType,其值为:
    * constructor:说明该方法用在构造方法上;
    * field:说明盖注解用在属性上;
    * local_variable:局部变量上;
    * method:用在方法上;
    * package:用在包声明上;
    * parameter:用在参数上;
    * type:用在类或接口上;

  • @Retention:表示需要在什么级别保存该注解信息,可能的参数值RetentionPolicy为:
    source:表示该注解会被编译器丢弃
    class:说明该注解会在.class文件中,但会被JVM丢弃
    runtime:jvm将在运行期间保留,因此可以通过反射机制来读取注解信息

  • @Documented:将该注解包含在JavaDoc中。表示此注解会被javadoc工具提取成文档。

  • @Inherited:允许子类继承父类中的注解。

自定义注解

  1. 定义注解
import java.lang.annotation.*;
@Target(ElementType.METHOD)		//说明此注解用在方法上
@Retention(RetentionPolicy.RUNTIME)		//说明是运行级别
public @interface Info {
     
	int id();			//为区分接口与类,在后面加上()
	String des() default "暂无信息";
}
  1. 定义目标类
public class TestInfo {
     
	@Info(id=1,des="show方法")
	public void show() {
     
		System.out.println("阴雨绵绵。。。");
	}
	@Info(id=2)
	public String getInfo() {
     
		return "欸。。。";
	}
	public void description(){
     
		System.out.println("真是应景。。。");
	}
}
  1. 定义测试类
public class InfoTracker {
     
	public static void main(String[] args) {
     
		test(TestInfo.class);
	}
	public static void test(Class<TestInfo> cl) {
     
		Info info = null;
		for( Method method : cl.getDeclaredMethods() ){
     	//循环给定类中的所有方法。也可以给定包路径,自动扫描该包下的所有类
			if( method.isAnnotationPresent( Info.class ) ){
     
				//method.getAnnotations();	//获取这个方法上的所有注解
				
				//现在我们只想知道是否有我们给定的注解Info
				System.out.println( method.getName() + "有Info注解" );
				
				info = method.getAnnotation(Info.class);
				System.out.println(info.id() + "-" + info.des());
			}else{
     
				System.err.println( method.getName() + "没有Info注解" );
			}
		}
	}
}

Java注解模拟实现Junit

  1. 创建注解类
import java.lang.annotation.*;

@Target(value={
     ElementType.METHOD})		//目标:作用域方法		//两种写法
@Retention(RetentionPolicy.RUNTIME)		//保留范围:运行时保留,不会被jvm丢弃
public @interface Beta {
     
	//这个注解类中不需要任何属性
}
  1. 编写测试用例类
public class Test {
     
	@Beta	//加上自定义的测试注解
	public void test(){
     
		System.out.println("SUCCESS!");
	}
	@Beta
	public void test2(){
     
		System.out.println("成功了!哈哈哈...");
	}
	@Beta
	public void test3(){
     
		System.err.println("嘻嘻嘻...");
	}
}
  1. 编写注解方法的操作测试类
public class TestBeta {
     
	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
     
		Class clazz = Test.class;
		
		Method[] methods = clazz.getMethods();
		if(methods != null){
     
			for(Method method : methods){
     
				boolean isAP = method.isAnnotationPresent(Beta.class);
				if(isAP){
     
					method.invoke(clazz.newInstance(), null);
				}
			}
		}
	}
}

注解模拟Hibernate中根据实体类在数据库建表的方法

  1. 创建用来指定表名的注解
import java.lang.annotation.*;
@Target(ElementType.TYPE)		//说明作用在类上
@Retention(RetentionPolicy.RUNTIME)	//运行时级别
public @interface TableName {
     
	public String name() default "";
}
  1. 创建用来指定类型的注解
import java.lang.annotation.*;
@Target(ElementType.FIELD)		//说明用在属性上
@Retention(RetentionPolicy.RUNTIME)
public @interface Type {
     
	public String type() default "varchar(20)";
	public Constraints constraints() default @Constraints;
}
  1. 创建指定约束的注解
@Target(ElementType.FIELD)		//说明在属性上
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
     
	public boolean primaryKey() default false;	//是否为主键
	public boolean allowNull() default true;	//是否可为空
	public boolean unique() default false;		//是否唯一
	public boolean identity() default false;	//是否自增
}
  1. 创建实体类
@TableName
public class StuInfo {
     
	@Type(type="int" ,constraints=@Constraints(primaryKey=true,identity=true))
	private int usid;
	
	@Type(type="varchar(200)" ,constraints=@Constraints(allowNull=false,unique=true))
	private String sname;
	
	@Type(type="int")
	private int age;
	
	@Type(constraints=@Constraints(unique=true))
	private String tel;
	public int getUsid() {
     
		return usid;
	}
	public void setUsid(int usid) {
     
		this.usid = usid;
	}
	public String getSname() {
     
		return sname;
	}
	public void setSname(String sname) {
     
		this.sname = sname;
	}
	public int getAge() {
     
		return age;
	}
	public void setAge(int age) {
     
		this.age = age;
	}
	public String getTel() {
     
		return tel;
	}
	public void setTel(String tel) {
     
		this.tel = tel;
	}
}
  1. 创建测试类
public class TableCreator {
     
	public static void main(String[] args) {
     
		TableCreator tc = new TableCreator();
		tc.run();
	}
	static{
     
		try {
     
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
     
			e.printStackTrace();
		}
	}
	public void run(){
     
		Connection con = null;
		Statement stmt = null;
		try {
     
			con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","数据库用户名","密码");
			stmt = con.createStatement();
			String sql = this.getSql(StuInfo.class);
			System.out.println(sql);
			stmt.execute(sql);	//执行sql
			System.out.println("创建成功");
		} catch (Exception e) {
     
			System.err.println("创建失败");
			e.printStackTrace();
		}finally {
     
			try {
     
				if(stmt != null){
     
					stmt.close();
				}
				if( con != null ){
     
					con.close();
				}
			} catch (Exception e) {
     
				e.printStackTrace();
			}
		}
	}
	
	//建表语句
	public String getSql(Class<?> cl){
     
		TableName tn = cl.getAnnotation(TableName.class);
		if(tn == null){
     
			return null;
		}
		String tableName = tn.name();
		if( tableName == null || "".equals(tableName) ){
     
			tableName = cl.getSimpleName();	//这里不要使用getName(),那样会返回带有包路径的字符串值
		}
		//如果需要考虑性能,建议使用StringBuffer
		StringBuffer sbf = new StringBuffer();
		sbf.append("create table ").append(tableName).append("(");
		//拼接列  ->  获取这个对象中的所有属性  ->  判断属性上是否有Type注解
		Field[] fields = cl.getDeclaredFields();
		if(fields == null || fields.length <= 0){
     
			return null;
		}
		Type type = null;
		for( Field field : fields ){
     
			type = field.getAnnotation(Type.class);
			if(type != null){
     
				sbf.append( field.getName() ).append(" ").append( type.type() );
				//这个列上的约束
				if( type.constraints().primaryKey() ){
     	//如果是主键
					sbf.append(" primary key");
					if( type.constraints().identity() ){
     //则需要判断是否自增
						sbf.append(" auto_increment");
					}
				}else{
     //不是主键,判断是否可为空,是否唯一
					if( !type.constraints().allowNull() ){
     	//不可为空
						sbf.append(" not null");
					}
					if( type.constraints().unique() ){
     	//唯一
						sbf.append(" unique");
					}
				}
				sbf.append(",");
			}
		}
		String sql = sbf.toString();
		//处理最后一个多余的逗号,并加上反括号
		sql = sql.substring(0,sql.lastIndexOf(",")) + ")";
		return sql;
	}
}

你可能感兴趣的:(Java学习随笔,注解,java)