在Java中,避免显式使用数据库列名、数据类型等是否更好?

在Java中,避免显式使用数据库列名、数据类型等是否更好?,java,jdbc,Java,Jdbc,在从数据库表获取结果时,避免显式使用(硬编码)数据库列标题、数据类型等是否被认为是更好的做法?我想说的是——假装我对数据库的结构一无所知,然后让程序运行(从而使它变得更长更复杂),或者直接在代码中使用它(或者可能将大多数信息列为类顶部的常量),这是更好的做法吗 例如,从表中检索数据有以下两种方法 简单的方法是: ArrayList<String> userNames = new ArrayList<>(); ArrayList<Blob> profilePic

在从数据库表获取结果时,避免显式使用(硬编码)数据库列标题、数据类型等是否被认为是更好的做法?我想说的是——假装我对数据库的结构一无所知,然后让程序运行(从而使它变得更长更复杂),或者直接在代码中使用它(或者可能将大多数信息列为类顶部的常量),这是更好的做法吗

例如,从表中检索数据有以下两种方法

简单的方法是:

ArrayList<String> userNames = new ArrayList<>();
ArrayList<Blob> profilePictures = new ArrayList<>();

// this method presumes that there are columns named user_name and 
// profile_picture and that they hold string and blob values
// respectively

while(resultSet.next()) {
    userNames.add(resultSet.getString("user_name"));
    profilePictures.add(resultSet.getBlob("profile_picture"));
}
ResultSetMetaData meta = resultSet.getMetaData();

ArrayList<String> columnHeaders = new ArrayList<>();

// doesn't know what the column headers are
for (int i = 1; i <= meta.getColumnCount(); i++) {
    columnHeaders.add(meta.getColumnName(i));
}

ArrayList<ArrayList<Object>> data = new ArrayList<>();

for(int i=0; i<columnHeaders.size(); i++) {
    data.add(new ArrayList<Object>());
}

for(int i=0; resultSet.next(); i++) {
    for (String header : columnHeaders) {
        // no presuming what the data type will be
        int type = meta.getColumnType(i);
        if(type == Types.VARCHAR) {
             data.get(i).add(resultSet.getString(header));
         } else if(type == Types.BLOB) {
            data.get(i).add(resultSet.getBlob(header));
         }
    }
}
ArrayList userNames=new ArrayList();
ArrayList profilePictures=新建ArrayList();
//此方法假定存在名为user\u name和
//profile_图片,它们包含字符串和blob值
//分别
while(resultSet.next()){
userNames.add(resultSet.getString(“用户名”);
添加(resultSet.getBlob(“profile_picture”);
}
。。。另一种方式是:

ArrayList<String> userNames = new ArrayList<>();
ArrayList<Blob> profilePictures = new ArrayList<>();

// this method presumes that there are columns named user_name and 
// profile_picture and that they hold string and blob values
// respectively

while(resultSet.next()) {
    userNames.add(resultSet.getString("user_name"));
    profilePictures.add(resultSet.getBlob("profile_picture"));
}
ResultSetMetaData meta = resultSet.getMetaData();

ArrayList<String> columnHeaders = new ArrayList<>();

// doesn't know what the column headers are
for (int i = 1; i <= meta.getColumnCount(); i++) {
    columnHeaders.add(meta.getColumnName(i));
}

ArrayList<ArrayList<Object>> data = new ArrayList<>();

for(int i=0; i<columnHeaders.size(); i++) {
    data.add(new ArrayList<Object>());
}

for(int i=0; resultSet.next(); i++) {
    for (String header : columnHeaders) {
        // no presuming what the data type will be
        int type = meta.getColumnType(i);
        if(type == Types.VARCHAR) {
             data.get(i).add(resultSet.getString(header));
         } else if(type == Types.BLOB) {
            data.get(i).add(resultSet.getBlob(header));
         }
    }
}
ResultSetMetaData=resultSet.getMetaData();
ArrayList columnHeaders=新的ArrayList();
//不知道列标题是什么

对于(int i=1;i我想没有关于哪种方法更好的既定规则,具体情况各不相同。如果一个表只有两列,则可以对列名进行硬编码,而不必经历循环迭代的麻烦


但是,如果您有一个包含40列的表,那么使用硬编码的值,代码就会变得难看/不可读,在这种情况下,您可以选择迭代方法,除非您正在编写一个通用中间件,否则您无法避免它。在任何应用程序中的某个时候,您都必须将数据库列值存储到语言variab中le,反之亦然,此时您需要知道列名并将其写入代码。

答案将在很大程度上取决于您试图实现的目标。根据我个人的经验,不是,但是种类a,是的。很多API(如hibernate)处理将表/列映射到对象的问题,因此在某些时候,您必须知道表/列名是什么,但您希望减少直接访问该信息的次数,因此,如果表/列名发生更改,您不会在整个代码中尝试查找它,这两个代码段之间的主要区别并不明显在他们对列的假设中,但在他们返回的数据结构中。两者都做得很差,但第一个明显更差。为什么第一个更差?意味着他们做得很差的主要缺陷是什么?