我正在尝试在
java中开发通用DAO.我尝试了以下内容.这是
实现通用DAO的好方法?我不想使用hibernate.我试图使它尽可能通用,这样我就不必一遍又一遍地重复相同的代码.
实现通用DAO的好方法?我不想使用hibernate.我试图使它尽可能通用,这样我就不必一遍又一遍地重复相同的代码.
public abstract class AbstractDAO<T> {
protected ResultSet findbyId(String tablename,Integer id){
ResultSet rs= null;
try {
// the following lines are not working
pStmt = cn.prepareStatement("SELECT * FROM "+ tablename+ "WHERE id = ?");
pStmt.setInt(1,id);
rs = pStmt.executeQuery();
} catch (sqlException ex) {
System.out.println("ERROR in findbyid " +ex.getMessage() +ex.getCause());
ex.printstacktrace();
}finally{
return rs;
}
}
}
我现在有:
public class UserDAO extends AbstractDAO<User>{
public List<User> findbyid(int id){
Resultset rs =findbyid("USERS",id) // "USERS" is table name in DB
List<Users> users = convertToList(rs);
return users;
}
private List<User> convertToList(ResultSet rs) {
List<User> userList= new ArrayList();
User user= new User();;
try {
while (rs.next()) {
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setFname(rs.getString("fname"));
user.setLname(rs.getString("lname"));
user.setUsertype(rs.getInt("usertype"));
user.setPasswd(rs.getString("passwd"));
userList.add(user);
}
} catch (sqlException ex) {
Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE,null,ex);
}
return userList;
}
}
解决方法
如果你能使用Spring,我会建议以下改进:
>让Spring进行异常处理.
>使用JdbcTemplate而不是自己创建预准备语句.
独立于使用Spring,我将推荐以下内容:
>不要将表名作为参数发送.这应该在初始化阶段完成.
>在id参数上使用String,因为它更通用.
>考虑返回通用对象而不是集合,因为集合应始终只包含一个对象.
一个改进的AbstractDao与Spring:
import java.util.Collection;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public abstract class AbstractDao<T> {
protected final RowMapper<T> rowMapper;
protected final String findByIdsql;
protected final JdbcTemplate jdbcTemplate;
protected AbstractDao(RowMapper<T> rowMapper,String tableName,JdbcTemplate jdbcTemplate) {
this.rowMapper = rowMapper;
this.findByIdsql = "SELECT * FROM " + tableName + "WHERE id = ?";
this.jdbcTemplate = jdbcTemplate;
}
public Collection<T> findById(final String id) {
Object[] params = {id};
return jdbcTemplate.query(findByIdsql,params,rowMapper);
}
}
如您所见,没有异常处理或使用原始sql类进行黑客攻击.此模板为您关闭ResultSet,我在您的代码中看不到.
而UserDao:
import java.sql.ResultSet;
import java.sql.sqlException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
public class UserDao extends AbstractDao<User> {
private final static String TABLE_NAME = "USERS";
public UserDao(JdbcTemplate jdbcTemplate) {
super(new UserRowMapper(),TABLE_NAME,jdbcTemplate);
}
private static class UserRowMapper implements RowMapper<User> {
public User mapRow(ResultSet rs,int rowNum) throws sqlException {
User user = new User();
user.setUserName(rs.getString("username"));
user.setFirstName(rs.getString("fname"));
user.setLastName(rs.getString("lname"));
return user;
}
}
}
更新:
当您知道id和id对应于数据库中的单个行时,您应该考虑返回通用对象而不是集合.
public T findUniqueObjectById(final String id) {
Object[] params = {id};
return jdbcTemplate.queryForObject(findByIdsql,rowMapper);
}
这使您的服务代码更具可读性,因为您不需要从列表中检索用户,而只需:
User user = userDao.findUniqueObjectById("22");