带有@SqlQuery 和@RegisterBeanMapper 的Bean 映射器无法实例化JDBI V3
Bean mapper with @SqlQuery and @RegisterBeanMapper cant instantiate JDBI V3
如文档所示,我不能将 Jdbi 与 Dao 接口一起使用,请参阅 http://jdbi.org/#_reflection_mappers
它抛出下一个异常:
Exception in thread "main" java.lang.IllegalArgumentException: A bean, model.tipolog.TipoLog, was mapped which was not instantiable
List<TipoLog> tipoLogs1=jdbi.withExtension(TipoLogDao.class,dao->{
return dao.listAllLogs();
});
public interface TipoLogDao {
@SqlQuery("SELECT * FROM tamble")
@RegisterBeanMapper(TipoLog.class)
List<TipoLog> listAllLogs();
}
public class TipoLog {
private String IdTipoLog;
private String Nombre;
private String Descripcion;
private String Activo;
@ConstructorProperties({"IdTipoLog", "Nombre", "Descripcion", "Activo"})
public TipoLog(String IdTipoLog, String Nombre, String Descripcion, String Activo) {
this.IdTipoLog = IdTipoLog;
this.Nombre = Nombre;
this.Descripcion = Descripcion;
this.Activo = Activo;
}
}
注意:此解决方案有效,但如果您想使用特定构造函数(不是默认构造函数),那么此答案不是您要找的那个。正如 所说,使用 @RegisterConstructorMapper
而不是 @RegisterBeanMapper
。 BeanMapper
仅使用默认构造函数并设置属性值。要使用特定的构造函数,解决方案是使用 ConstructorMapper
.
您的 TipoLog
class 需要一个 默认构造函数 。这有效:
User.java
import java.beans.ConstructorProperties;
public class User {
int id;
String name;
// required default constructor
public User() {
super();
}
@ConstructorProperties({ "id", "name" })
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
// getter, setter, hashCode, equals, toString
}
UserDao.java
import java.util.List;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
public interface UserDao {
@SqlUpdate("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
void createTable();
@SqlUpdate("INSERT INTO user(id, name) VALUES (?, ?)")
void insertPositional(int id, String name);
@SqlQuery("SELECT * FROM user ORDER BY name")
@RegisterBeanMapper(User.class)
List<User> listUsers();
}
ConstructorPropertiesExplore.java
import java.util.List;
import static org.assertj.core.api.Assertions.*;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.sqlobject.SqlObjectPlugin;
public class ConstructorPropertiesExplore {
public static void main(String[] args) {
Jdbi jdbi = Jdbi.create("jdbc:h2:mem:test");
jdbi.installPlugin(new SqlObjectPlugin());
List<User> users = jdbi.withExtension(UserDao.class, dao -> {
dao.createTable();
dao.insertPositional(0, "Alice");
dao.insertPositional(1, "Bob");
dao.insertPositional(2, "Clarice");
dao.insertPositional(3, "David");
return dao.listUsers();
});
assertThat(users).containsExactly(new User(0, "Alice"), new User(1, "Bob"), new User(2, "Clarice"),
new User(3, "David"));
}
}
您不需要默认构造函数。
使用@RegisterConstructorMapper 而不是@RegisterBeanMapper。
如文档所示,我不能将 Jdbi 与 Dao 接口一起使用,请参阅 http://jdbi.org/#_reflection_mappers 它抛出下一个异常:
Exception in thread "main" java.lang.IllegalArgumentException: A bean, model.tipolog.TipoLog, was mapped which was not instantiable
List<TipoLog> tipoLogs1=jdbi.withExtension(TipoLogDao.class,dao->{
return dao.listAllLogs();
});
public interface TipoLogDao {
@SqlQuery("SELECT * FROM tamble")
@RegisterBeanMapper(TipoLog.class)
List<TipoLog> listAllLogs();
}
public class TipoLog {
private String IdTipoLog;
private String Nombre;
private String Descripcion;
private String Activo;
@ConstructorProperties({"IdTipoLog", "Nombre", "Descripcion", "Activo"})
public TipoLog(String IdTipoLog, String Nombre, String Descripcion, String Activo) {
this.IdTipoLog = IdTipoLog;
this.Nombre = Nombre;
this.Descripcion = Descripcion;
this.Activo = Activo;
}
}
注意:此解决方案有效,但如果您想使用特定构造函数(不是默认构造函数),那么此答案不是您要找的那个。正如 @RegisterConstructorMapper
而不是 @RegisterBeanMapper
。 BeanMapper
仅使用默认构造函数并设置属性值。要使用特定的构造函数,解决方案是使用 ConstructorMapper
.
您的 TipoLog
class 需要一个 默认构造函数 。这有效:
User.java
import java.beans.ConstructorProperties;
public class User {
int id;
String name;
// required default constructor
public User() {
super();
}
@ConstructorProperties({ "id", "name" })
public User(int id, String name) {
super();
this.id = id;
this.name = name;
}
// getter, setter, hashCode, equals, toString
}
UserDao.java
import java.util.List;
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
public interface UserDao {
@SqlUpdate("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
void createTable();
@SqlUpdate("INSERT INTO user(id, name) VALUES (?, ?)")
void insertPositional(int id, String name);
@SqlQuery("SELECT * FROM user ORDER BY name")
@RegisterBeanMapper(User.class)
List<User> listUsers();
}
ConstructorPropertiesExplore.java
import java.util.List;
import static org.assertj.core.api.Assertions.*;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.sqlobject.SqlObjectPlugin;
public class ConstructorPropertiesExplore {
public static void main(String[] args) {
Jdbi jdbi = Jdbi.create("jdbc:h2:mem:test");
jdbi.installPlugin(new SqlObjectPlugin());
List<User> users = jdbi.withExtension(UserDao.class, dao -> {
dao.createTable();
dao.insertPositional(0, "Alice");
dao.insertPositional(1, "Bob");
dao.insertPositional(2, "Clarice");
dao.insertPositional(3, "David");
return dao.listUsers();
});
assertThat(users).containsExactly(new User(0, "Alice"), new User(1, "Bob"), new User(2, "Clarice"),
new User(3, "David"));
}
}
您不需要默认构造函数。 使用@RegisterConstructorMapper 而不是@RegisterBeanMapper。