将SQL语句动态添加到JDBI StatementLocator中



如何添加包含queryname,statement的Map的内容Handle的语句缓存,以便在SQL对象中使用,而不使用繁琐的模板组文件,也不影响在对象注释中使用原始SQL的能力,同时还保留@Define的功能?

Map<String,String> querySource = new HashMap<>();
querySource.put("sql/BasicDao/simpleSelect","Select * FROM <schemaName>.table_of_vast_importance")
handle.somehowAddToStatementCache(querySource)
...
public interface BasicDao {
    @SqlQuery("sql/BasicDao/simpleSelect")
    BasicBean selectFromTable(@Define("schemaName") String);
    @SqlQuery("SELECT ... FROM ...")
    BasicBean moreComplicatedSelect(@Define("schemaName) String)
    ...

}

我希望通过程序为SQL对象的应用程序加载生成基本的CRUD操作,以消除为数据库中每个表的每个操作编写样板SQL的需要。问题是@Define似乎只在用@UseStringTemplate3StatementLocator注释SQL对象接口时起作用;然而,CCD_ 6似乎没有提供一种明显的方法来添加动态生成的查询。

如果您考虑将Byte Buddy用于运行时(字节码)代码生成,以下是我的机器上经过单元测试的代码。这显示了一个before/after示例。我希望它能有所帮助。

原始来源:

@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;
    }
}

最新更新