步骤 2 : 自定义hibernate注解 步骤 3 : 运用在Hero对象上 步骤 4 : 解析注解 步骤 5 : 可运行项目
hibernate有两种配置方式,分别是*.hbm.xml 配置方式 和注解方式。 虽然方式不一样,但是都是用于解决如下问题:
1. 当前类是否实体类 2. 对应的表名称 3. 主键对应哪个属性, 自增长策略是什么,对应字段名称是什么 4. 非主键属性对应字段名称是什么 接下来,我会做一套仿hibernate的注解,并且在一个实体类Hero上运用这些注解,并通过反射解析这些注解信息,来解决上述的问题
参考hibernate的 注解配置方式 ,自定义5个注解,分别对应hibernate中用到的注解:
hibernate_annotation.MyEntity 对应 javax.persistence.Entity hibernate_annotation.MyTable 对应 javax.persistence.Table hibernate_annotation.MyId 对应 javax.persistence.Id hibernate_annotation.MyGeneratedValue 对应 javax.persistence.GeneratedValue hibernate_annotation.MyColumn 对应 javax.persistence.Column package hibernate_annotation;
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 MyEntity {
}
package hibernate_annotation;
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 MyTable {
String name();
}
package hibernate_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyId {
}
package hibernate_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyGeneratedValue {
String strategy();
}
package hibernate_annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyColumn {
String value();
}
像以注解方式配置Product类 那样,在Hero类上运用这些自定义注解:
当注解的方法是value的时候,给这个注解赋值时,本来应该是: @MyColumn(value="name_") 现在可以简略一点,写为 @MyColumn("name_") 只有当名称是value的时候可以这样,其他名称如name,stratgy等不行 package pojo;
import hibernate_annotation.MyColumn;
import hibernate_annotation.MyEntity;
import hibernate_annotation.MyGeneratedValue;
import hibernate_annotation.MyId;
import hibernate_annotation.MyTable;
@MyEntity
@MyTable(name="hero_")
public class Hero {
private int id;
private String name;
private int damage;
private int armor;
@MyId
@MyGeneratedValue(strategy = "identity")
@MyColumn("id_")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@MyColumn("name_")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@MyColumn("damage_")
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
@MyColumn("armor_")
public int getArmor() {
return armor;
}
public void setArmor(int armor) {
this.armor = armor;
}
}
创建一个解析类ParseHibernateAnnotation ,获取Hero类上配置的注解信息,其运行结果如图所示。
思路如下: 1. 首先获取Hero.class类对象 2. 判断本类是否进行了MyEntity 注解 3. 获取注解 MyTable 4. 遍历所有的方法,如果某个方法有MyId注解,那么就记录为主键方法primaryKeyMethod 5. 把主键方法的自增长策略注解MyGeneratedValue和对应的字段注解MyColumn 取出来,并打印 6. 遍历所有非主键方法,并且有MyColumn注解的方法,打印属性名称和字段名称的对应关系。 package test;
import java.lang.reflect.Method;
import hibernate_annotation.MyColumn;
import hibernate_annotation.MyEntity;
import hibernate_annotation.MyGeneratedValue;
import hibernate_annotation.MyId;
import hibernate_annotation.MyTable;
import pojo.Hero;
public class ParseHibernateAnnotation {
public static void main(String[] args) {
Class<Hero> clazz = Hero.class;
MyEntity myEntity = (MyEntity) clazz.getAnnotation(MyEntity.class);
if (null == myEntity) {
System.out.println("Hero类不是实体类");
} else {
System.out.println("Hero类是实体类");
MyTable myTable= (MyTable) clazz.getAnnotation(MyTable.class);
String tableName = myTable.name();
System.out.println("其对应的表名是:" + tableName);
Method[] methods =clazz.getMethods();
Method primaryKeyMethod = null;
for (Method m: methods) {
MyId myId = m.getAnnotation(MyId.class);
if(null!=myId){
primaryKeyMethod = m;
break;
}
}
if(null!=primaryKeyMethod){
System.out.println("找到主键:" + method2attribute( primaryKeyMethod.getName() ));
MyGeneratedValue myGeneratedValue =
primaryKeyMethod.getAnnotation(MyGeneratedValue.class);
System.out.println("其自增长策略是:" +myGeneratedValue.strategy());
MyColumn myColumn = primaryKeyMethod.getAnnotation(MyColumn.class);
System.out.println("对应数据库中的字段是:" +myColumn.value());
}
System.out.println("其他非主键属性分别对应的数据库字段如下:");
for (Method m: methods) {
if(m==primaryKeyMethod){
continue;
}
MyColumn myColumn = m.getAnnotation(MyColumn.class);
//那些setter方法上是没有MyColumn注解的
if(null==myColumn)
continue;
System.out.format("属性: %s\t对应的数据库字段是:%s%n",method2attribute(m.getName()),myColumn.value());
}
}
}
private static String method2attribute(String methodName) {
String result = methodName; ;
result = result.replaceFirst("get", "");
result = result.replaceFirst("is", "");
if(result.length()<=1){
return result.toLowerCase();
}
else{
return result.substring(0,1).toLowerCase() + result.substring(1,result.length());
}
}
}
因为本知识点涉及到的自定义类型比较多,为了保证大家顺利看到运行结果,把本项目打包后在右上角下载
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
问答区域
2024-03-25
各位大佬,能解释一下“有当名称是value的时候可以这样,其他名称如name,stratgy等不行”吗?
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2022-03-22
自定义注解问题
1 个答案
四方1 跳转到问题位置 答案时间:2023-08-01 你map.put("mz","rose")干嘛,不应该是map.put("name","rose")吗?
况且你这输出好像跟注解没啥关系啊,只是类型匹配,解析的数据都是你手动put进去的啊?
相当于@Demo2()里面的东西白写了,根本没用到
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
2021-08-22
不允许在此位置使用注释
2017-08-12
步骤4里面的方法 methodtoattribute 替换的字符串应该是"set"而不是"is"
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|