注意以下类都没有定义package,在默认package下。
1.0 定义注解, 要求 RetentionPolicy.SOURCE
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Id {
String column();
String type();
String generator();
}
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Persistent {
String table();
}
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Property {
String column();
String type();
}
2.0 注解处理器
@SupportedAnnotationTypes({“Persistent”, “Id”, “Property”}) 指明注解处理器可以处理哪些注解
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Set;
@SupportedSourceVersion(SourceVersion.RELEASE_8)
// 指定可处理 @Persistent、@Id、@Property 三个Annotation
@SupportedAnnotationTypes({"Persistent", "Id", "Property"})
public class HibernateAnnotationProcessor extends AbstractProcessor {
// 循环处理每个需要处理的程序对象
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// 定义一个文件输出流,用于生成额外的文件
PrintStream ps = null;
try {
// 遍历每个被 @Persistent修饰的class文件
for (Element t : roundEnv.getElementsAnnotatedWith(Persistent.class)) {
// 获取正在处理的类名
Name clazzName = t.getSimpleName();
// 获取类定义前的 @Persistent Annotation
Persistent per = t.getAnnotation(Persistent.class);
// 创建文件输出流
ps = new PrintStream(new FileOutputStream(clazzName + ".hbm.xml"));
// 执行输出
ps.println("<?xml version=\"1.0\"?>");
ps.println("<!DOCTYPE hibernate-mapping PUBLIC");
ps.println(" \"-//Hibernate/Hibernate "
+ "Mapping DTD 3.0//EN\"");
ps.println(" \"http://www.hibernate.org/dtd/"
+ "hibernate-mapping-3.0.dtd\">");
ps.println("<hibernate-mapping>");
ps.print(" <class name=\"" + t);
// 输出per的table()的值 注解使用相当于是注解的实例,注解的实例调用注解的方法,获取传入的值
ps.println("\" table=\"" + per.table() + "\">");
for (Element f : t.getEnclosedElements()) {
// 只处理成员变量上的Annotation
if (f.getKind() == ElementKind.FIELD) {
// 获取成员变量定义前的@Id Annotation
Id id = f.getAnnotation(Id.class);
// 当@Id Annotation存在时输出<id.../>元素
if (id != null) {
ps.println(" <id name=\""
+ f.getSimpleName()
+ "\" column=\"" + id.column()
+ "\" type=\"" + id.type()
+ "\">");
ps.println(" <generator class=\""
+ id.generator() + "\"/>");
ps.println(" </id>");
}
// 获取成员变量定义前的@Property Annotation
Property p = f.getAnnotation(Property.class);
// 当@Property Annotation存在时输出<property.../>元素
if (p != null) {
ps.println(" <property name=\""
+ f.getSimpleName()
+ "\" column=\"" + p.column()
+ "\" type=\"" + p.type()
+ "\"/>");
}
}
}
ps.println(" </class>");
ps.println("</hibernate-mapping>");
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (ps != null) {
try {
ps.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return true;
}
}
3.0 使用注解
@Persistent(table = "person_inf")
public class Person {
@Id(column = "person_id", type = "integer", generator = "identity")
private int id;
@Property(column = "person_name", type = "string")
private String name;
@Property(column = "person_age", type = "integer")
private int age;
//无参数的构造器
public Person() {
}
//初始化全部成员变量的构造器
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
4.0 让注解处理器生效
首先要编译 注解和注解处理器
D:\ast>javac -encoding utf-8 *.java
此时编译 注解处理器还没有起作用,Person的编译没有触发 注解处理器的执行。
其次, -processor 指定注解处理器,重新编译Person.java,
说明: -processor
D:\ast>javac -encoding utf-8 -processor HibernateAnnotationProcessor Person.java
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Person" table="person_inf">
<id name="id" column="person_id" type="integer">
<generator class="identity"/>
</id>
<property name="name" column="person_name" type="string"/>
<property name="age" column="person_age" type="integer"/>
</class>
</hibernate-mapping>