3

CSV からデータを抽出する方法は 2 つあります。

private Car processCar (String [] row) {
    Car c = new Car();
    c.setCarId(Integer.parseInt(row[CSVColumns.carid.index]));
    ....
    return c;
}

private Driver processDriver(String[] row) {
    Driver d = new Driver(row[CSVColumns.name.index]);
    sys.setAge(row[CSVColumns.age.index]);
    ...
    return d;
}

ここで、データベースからデータを抽出する際に、これら 2 つの方法を再度実行する必要がありますが、わずかな変更があります。

private Car processCar (ResultSet rs) {
    Car c = new Car();
    c.setCarId(rs.getInt("Id"));
    ....
    return c;
}

private Driver processDriver(ResultSet) {
    Driver d = new Driver(rs.getString("Name));
    sys.setAge(rs.getString("Age"));
    .....
    return d;
}

繰り返す必要がないように、これを単純化する方法はありますか? さらに、各メソッドには多くのゲッター/セッターが含まれているため、コピーして貼り付けて変更するのは嫌いです...

4

4 に答える 4

1

One option is to write a method that takes a result set and converts to return a string array. Depending on your database library, this may be largely built in. So you create something like

String[] ResultSetToStrings(ResultSet aResultSet)

Then your call looks something like either

processCar(["1994","Ford","Probe","etc"]);

or

processCar(ResultSetToStrings(aResultSet));

and you discard the ResultSet versions of your code.

This may incur some efficiency penalty (probably negligble - time spent converting to CSV and some extra string manipulation). Also be sure to make sure your CSV comes out in the right order (may need to explicitly state column names and order in your SQL query and.or consult the CSVColumns object in your conversion routine) and handle things like multiple rows, blanks, commas in the field values, etc.

The reverse might also work - change your String[] into a result set. In fact, again depending on your database driver, this might be built in.

于 2012-10-31T20:19:48.400 に答える
1

データ ソースを抽象化し、共通のインターフェイスを使用する

ResultSetアイデアは、または CSV を一貫したインターフェイスの背後にある共通のものに変換する共通のアダプターを用意することです。

interface CarDataSource {

    getCarId();
    //...

}

そして2つの実装:

class CsvDataSource implements CarDataSource {

    private final String[] row;

    public CsvDataSource(String[] row) {
        this.row = row;
    }

    public int getCarId() {
        return Integer.parseInt(row[CSVColumns.carid.index]);
    }

    //...

}

class ResultSetDataSource implements CarDataSource {

    private final ResultSet rs;

    public ResultSetDataSource(ResultSet rs) {
        this.rs = rs;
    }

    public int getCarId() {
        return Integer.parseInt(rs.getString("Name));
    }

    //...

}

これはあなたがそれを使用する方法です:

private Car processCar(CarDataSource s) {
    Car c = new Car();
    c.setCarId(s.getCarId());
    ....
    return c;
}

new CsvDataSource()または のいずれかを提供しますnew ResultSetDataSource()

2 つの実装を持つ抽象ファクトリ:

非常によく似たアプローチで、ファクトリを作成して抽象化します。

interface CarFactory {

    Car create();

}

2 つの実装:

class CsvCarFactory implements CarFactory {

    private final String[] row;

    public CsvDataSource(String[] row) {
        this.row = row;
    }

    public Car create() {
        Car c = new Car();
        c.setCarId(Integer.parseInt(row[CSVColumns.carid.index]));
        //...
        return c;
    }

}

class ResultSetCarFactory implements CarDataSource {

    private final ResultSet rs;

    public ResultSetCarFactory(ResultSet rs) {
        this.rs = rs;
    }

    public Car create() {
        Car c = new Car();
        c.setCarId(rs.getInt("Id"));
        //...
        return c;
    }

    //...

}

組み合わせ

上記のアプローチはどれも好きではありません。なぜなら、それらは多くの価値を追加せずに多くのボイラープレートを導入するからです。しかし、最初のアプローチは、それを減らすと有望です。

引数としてprocessCar()取るものを 1 つだけ用意してください。String[]ただし、 がある場合は、列を配列内の後続の項目に抽出することによりResultSet、最初に変換するだけです。String[]

public String[] toStringArray(ResultSet rs)

ResultSet基本フォーマットである逆方向への変換も可能ですが、ResultSet単独で実装するのははるかに困難です。

于 2012-10-31T20:21:43.557 に答える
0

Adapter解決策の 1 つは、インターフェイスを使用することです。


interface ParamAdapter {
    int getCarID();
    //...
}

class ResultSetParamAdapter implements ParamAdapter {

    private final ResultSet rs;

    public ResultSetParamAdapter(ResultSet rs) {
       this.rs = rs;
    }

    public int getCarID() {
        return rs.getInt("Id");
    }

    //...
}

class StringArrayParamAdapter implements ParamAdapter {

    private String[] array;

    public ResultSetParamAdapter(String[] array) {
       this.array = array;
    }

    public int getCarID() {
        return Integer.parseInt(array[CSVColumns.carid.index]);
    }

    //...
}

3 つのドットは、必要になる可能性のある他の方法です。

于 2012-10-31T20:28:25.730 に答える
0

プログラムの側面を単純化できる別のアプローチ:

private Car processCar (String [] row) {
    return new Car(Integer.parseInt(row[CSVColumns.carid.index]));
}

private Driver processDriver(String[] row) {
     return new Driver(row[CSVColumns.name.index], row[CSVColumns.age.index]);
}

多くの場合、文字列よりも明確な型を使用することで作業が楽になりますが、文字列表現との間で変換できるようにします。次に、パーサーは、CSV 入力からのこれらの特殊な型の作成をサポートできます。そのため、タイプ セーフを追加すると、冗長性がなくなり、保守しやすくなります。

于 2012-10-31T20:23:35.973 に答える