我有两种方法可以从CSV中提取数据
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;
}
现在,在从数据库中提取数据时,我需要再次制作这两种方法,但需要稍作修改
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;
}
有没有办法简化这一点,以便我不必重复自己?另外,每种方法都包含很多getter / setter,所以我不想复制粘贴内容并进行更改......
答案 0 :(得分:1)
一种选择是编写一个获取结果集并转换为返回字符串数组的方法。根据您的数据库库,这可能主要是内置的。所以你创建类似
的东西String[] ResultSetToStrings(ResultSet aResultSet)
然后你的电话看起来像是
processCar(["1994","Ford","Probe","etc"]);
或
processCar(ResultSetToStrings(aResultSet));
并丢弃代码的ResultSet版本。
这可能会导致一些效率损失(可能是可忽略的 - 转换为CSV的时间和一些额外的字符串操作)。另外一定要确保你的CSV按照正确的顺序出现(可能需要在SQL查询中明确说明列名和顺序,或者在转换例程中查询CSVColumns对象)并处理多行,空格,逗号等内容在字段值等
反向也可能有效 - 将String []更改为结果集。实际上,同样取决于您的数据库驱动程序,这可能是内置的。
答案 1 :(得分:1)
我们的想法是使用通用适配器将ResultSet
或CSV转换为一致界面背后的常见内容:
interface CarDataSource {
getCarId();
//...
}
两个实现:
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()
。
非常相似的方法,创建和抽象工厂:
interface CarFactory {
Car create();
}
有两个实现:
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()
以String[]
为参数。但是,如果您有ResultSet
,只需将列提取到String[]
,然后将列提取到数组中的后续项目中:
public String[] toStringArray(ResultSet rs)
另一个方向的翻译也可以ResultSet
是基本格式,但ResultSet
更难单独实施。
答案 2 :(得分: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输入创建这些专用类型。因此,添加类型安全性也可以很长时间地消除冗余并使其更易于维护。
答案 3 :(得分:0)
一种解决方案可能是使用Adapter
接口。
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]);
}
//...
}
这三个点是您可能需要的其他方法。