java通用构造函数 [英] java generic constructors
问题描述
我目前有以下代码从数据库中检索数据,然后创建一个 User
。这个代码在许多我的classe使用创建其他对象,如新闻
,注释
等...
它使用apache commons dbutils。
final ResultSetHandler< User> handler = new ResultSetHandler< User>(){
@Override
public用户句柄(ResultSet rs)throws SQLException {
用户user = null;
if(rs.next()){
user = new User();
user.setId(rs.getInt(id));
user.setUsername(rs.getString(username));
user.setPassword(rs.getString(password));
}
return user;
}
};
final用户user = run.query(
SELECT id,username,password FROM users WHERE username =?AND active = 2 LIMIT 1;,handler,
username) ;
可以包装 QueryRunner
在一个通用类中,并覆盖查询方法,所以处理程序使用ResultSet来实现泛型 T
。我会确保任何 T
类型将构造函数接受 ResultSet
。
像这样:
public class QueryExecuter< T>扩展QueryRunner {
private ResultSetHandler< T> _handler;
public QueryExecuter(){// T类型用于测试haha
super();
handler = new ResultSetHandler< T>(){
@Override
public T handle(ResultSet rs)throws SQLException {
T object = null ;
if(rs.next()){
object = new T(rs);
}
return object;
}
};
}
}
我不知道你会明白,
我想到了这个问题,但是我希望这样,我可以使用一个AbstractClass而不是所有的不同的对象将扩展的泛型类型,但似乎我不能写一个抽象构造函数。我必须创建一个静态方法返回对象的实例,如:
public abstract class DatabaseEntity {
public static abstract DatabaseEntity create(ResultSet rs); //即使这样不起作用...
}
可能,是的?但它是一个坏主意。
您可以:
ResultSetHandler< T> {
ResultSetHandler< T>(Class< T> clazz){
this.clazz = clazz;
}
public T handle(ResultSet rs)throws SQLException {
T object = null;
if(rs.next()){
object = clazz.getConstructor(ResultSet.class).newInstance(rs)
}
return object;
}
}
然而,混合域和数据库是一个坏主意。然而,更好的是定义一个基于结果集创建对象的abtract方法:
抽象类ResultSetHandler< ; T> {
protected abstract T create(ResultSet rs);
public T handle(ResultSet rs)throws SQLException {
T object = null;
if(rs.next()){
object = create(rs);
}
return object;
}
}
然后,在实现类中,提供 create()
方法,而不是自己处理结果集,例如:
h = new ResultSetHandler< Person>(){
protected Person create(ResultSet rs){
return new Person(rs.getString(name));
}
}
I currently have the following code that retrieves data from the database and then create a User
. This code is used in many of my classe to create other objects such as News
, Comments
etc...
It uses apache commons dbutils.
final ResultSetHandler<User> handler = new ResultSetHandler<User>() {
@Override
public User handle(ResultSet rs) throws SQLException {
User user = null;
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
return user;
}
};
final User user = run.query(
"SELECT id, username, password FROM users WHERE username = ? AND active = 2 LIMIT 1;", handler,
username);
Would it be possible to wrap the QueryRunner
in a generic class and override the query method so the handler instanciate the generic T
with the ResultSet. I would make sure any T
type would ahve a constructor accepting a ResultSet
.
Like so :
public class QueryExecuter<T> extends QueryRunner {
private ResultSetHandler<T> _handler;
public QueryExecuter(){//The T type was for testing haha
super();
handler = new ResultSetHandler<T>() {
@Override
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = new T(rs);
}
return object;
}
};
}
}
I don't know if you'll understand, but I hope so, ask me if you want more details or a better explanation.
EDIT
I thought I could use a AbstractClass instead of the generic type that all of the differents objects would extends but it seems like I can't write an abstract constructor. Will I have to make a static method that return an instance of the object like:
public abstract class DatabaseEntity {
public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}
Possible, yes? But its a bad idea.
You could do:
class ResultSetHandler<T> {
ResultSetHandler<T>(Class<T> clazz) {
this.clazz = clazz;
}
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = clazz.getConstructor(ResultSet.class).newInstance(rs)
}
return object;
}
}
Mixing domain and database is a bad idea, however. What would be better, however, would be to define an abtract method that creates the object based on the resultset:
abstract class ResultSetHandler<T> {
protected abstract T create(ResultSet rs);
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = create(rs);
}
return object;
}
}
Then, in your implementing class, you only need to provide a create()
method instead of handling the result set yourself, for example:
h = new ResultSetHandler<Person>() {
protected Person create(ResultSet rs) {
return new Person(rs.getString("name"));
}
}
这篇关于java通用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!