如果您考虑使用Byte Buddy生成运行时(字节码)代码,以下是我机器上的单元测试代码。这显示了一个之前/之后的示例。我希望它有所帮助。
原始来源:
@RegisterMapper(TimezoneJDBIMapper.class)
public abstract class TimezoneJDBI {
@SqlUpdate("INSERT INTO timezone (timez_name, version) VALUES (:timezName, :version)")
@GetGeneratedKeys
public abstract long insert(@BindBean Timezone timezone);
}
没有注释的新源:
public abstract class TimezoneJDBI {
@GetGeneratedKeys
public abstract long insert(Timezone timezone);
}
使用onDemand
现在是完全动态的:
Class<? extends TimezoneJDBI> clazz = new ByteBuddy()
.withModifiers(TypeManifestation.ABSTRACT)
.subclass(TimezoneJDBI.class)
.method(ElementMatchers.named("insert"))
.withoutCode()
.annotateMethod(new SqlUpdateImpl("INSERT INTO timezone (timez_name, version) VALUES (:timezName, :version)"))
.annotateParameter(0, new BindBeanImpl())
.annotateType(new RegisterMapperImpl(new Class[]{TimezoneJDBIMapper.class}))
.make().load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER).getLoaded();
TimezoneJDBI dao = jdbi.onDemand(clazz);
对于注释,需要一些帮助器类(每个使用的注释一个,如 Byte Buddy 文档中所述):
class SqlUpdateImpl implements SqlUpdate {
private String value;
public SqlUpdateImpl(String value) {
this.value = value;
}
@Override
public Class<? extends Annotation> annotationType() {
return SqlUpdate.class;
}
@Override
public String value() {
return value;
}
}
class RegisterMapperImpl implements RegisterMapper {
private Class<? extends ResultSetMapper<?>>[] value;
public RegisterMapperImpl(Class<? extends ResultSetMapper<?>>[] value) {
this.value = value;
}
@Override
public Class<? extends Annotation> annotationType() {
return RegisterMapper.class;
}
@Override
public Class<? extends ResultSetMapper<?>>[] value() {
return value;
}
}
class BindBeanImpl implements BindBean {
@Override
public Class<? extends Annotation> annotationType() {
return BindBean.class;
}
@Override
public String value() {
return BindBeanImpl.BARE_BINDING;
}
}