我想知道jdbi sql api处理sql查询究竟是什么用于调试目的。 我的接口类是
public inteface myinteface{
@SqlQuery("select :c1 from tablename where cond = :cd")
String returnMeValue(@Bind("c1") String c1, @Bind("cd") Integer cd);
}
后来在另一个班级中调用String result = myinterfaceclassobject.returnMeValue("Name",1);
我没有得到预期的答案所以我想看看实际上是什么进入sql查询。那么有什么方法可以获得最终处理的查询吗?
答案 0 :(得分:8)
您可以通过编写SqlCustomizer来记录sql。
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizer;
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizerFactory;
import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizingAnnotation;
import org.skife.jdbi.v2.tweak.StatementCustomizer;
import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.SQLException;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SqlStatementCustomizingAnnotation(LogSqlFactory.Factory.class)
public @interface LogSqlFactory {
static class Factory implements SqlStatementCustomizerFactory {
@Override
public SqlStatementCustomizer createForMethod(Annotation annotation, Class sqlObjectType, Method method) {
return null;
}
@Override
public SqlStatementCustomizer createForType(Annotation annotation, Class sqlObjectType) {
return q -> q.addStatementCustomizer(new StatementCustomizer() {
@Override
public void beforeExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException {
System.out.println(stmt.toString());
}
@Override
public void afterExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException { }
@Override
public void cleanup(StatementContext ctx) throws SQLException { }
});
}
@Override
public SqlStatementCustomizer createForParameter(Annotation annotation, Class sqlObjectType, Method method, Object arg) {
return null;
}
}
}
只需包含此注释并在SqlObject中使用它。在您的情况下,使用此注释,
@LogSqlFactory
public inteface myinteface{
@SqlQuery("select :c1 from tablename where cond = :cd")
String returnMeValue(@Bind("c1") String c1, @Bind("cd") Integer cd);
}
如果使用自定义记录器进行记录,则使用beforeExecution方法。
答案 1 :(得分:0)
使用像log4jdbc这样的东西要容易得多,使用Manikandan的方法也会慢慢减慢你的代码。
但是,如果您仍想使用它并且您的项目语言级别不支持lambdas,则可以使用以下修改:
@Override
public SqlStatementCustomizer createForType(Annotation annotation, final Class sqlObjectType) {
return new SqlStatementCustomizer() {
@Override
public void apply(SQLStatement sqlStatement) throws SQLException {
sqlStatement.addStatementCustomizer(new StatementCustomizer() {
@Override
public void beforeExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException {
System.out.println(stmt.toString());
}
@Override
public void afterExecution(PreparedStatement stmt, StatementContext ctx) throws SQLException {
}
@Override
public void cleanup(StatementContext ctx) throws SQLException {
}
});
}
};
}
但是stmt.toString()不能保证返回SQL语句,它取决于实现。这对SQLite不起作用。
答案 2 :(得分:0)
基于@Manikandan's answer,我发现它无法与Jdbi> = 3.10一起使用,我对LogSqlFactory
进行了如下调整:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SqlStatementCustomizingAnnotation(LogSqlFactory.Factory.class)
public @interface LogSqlFactory {
class Factory implements SqlStatementCustomizerFactory {
@Override
public SqlStatementCustomizer createForType(Annotation annotation, Class sqlObjectType) {
SqlLogger sqlLogger = new SqlLogger() {
@Override
public void logBeforeExecution(StatementContext context) {
logSql(context);
}
};
return statement -> statement.setSqlLogger(sqlLogger);
}
private static void logSql(StatementContext context) {
System.out.println("Raw SQL:\n" + context.getRawSql());
System.out.println("Parsed SQL:\n" + context.getParsedSql().getSql());
System.out.println("Rendered SQL:\n" + context.getRenderedSql());
}
}
}
用LogSqlFactory
注释SqlObject接口以查看SQL语句:
@LogSqlFactory
public interface Dao {
@SqlQuery("select * from t")
List<?> selectAll();
}