0

我有三个单独的文件解析函数,它们将文本文件转换为对象,然后将这些值插入到 sqlite 数据库中。除了对象类之外,它们基本上都是相同的。

过程如下:

  1. 使用 http 下载文件
  2. 计算文件中的行数以进行进度计算
  3. 删除目标表中所有以前的记录
  4. 使用 BufferedReader 打开文件
  5. 一次读取 2000 行并将其转换为对象
  6. 在事务中将 2000 条记录插入到 sqlite
  7. 循环直到完成

我无法弄清楚如何使这段代码通用以允许任何类用于创建对象,然后决定使用哪个 DAL 函数来持久化数据。Java 不是我的第一语言,所以任何指导都会很棒。

这是我正在使用的代码:

public void downloadPendingPoleInspections() {

    int count;
    String filePath;
    Inspections inspections = Inspections.getInstance();

    filePath = Environment.getExternalStorageDirectory() + File.separator + "inspections.txt";

    try {

        downloadFile("http://localhost/api/inspectionservices.aspx?o=retrieve", "pendinginspections.txt", POST_PENDING_INSPECTIONS_PROGRESS_UPDATE);

        int totalInspections = getLineCount(filePath);

        inspections.deleteAllPendingInspections();          

        File file = new File(filePath);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;

        int i = 0;
        int j = 0;

        List<PendingInspection> batch = new ArrayList<PendingInspection>();

        while ((line = br.readLine()) != null) {
            String[] values = line.split(" ");

            PendingInspection pending = new PendingInspection(
                    Integer.parseInt(values[0]), values[1],
                    Double.parseDouble(values[2]),
                    Double.parseDouble(values[3]));

            batch.add(pending);
            i++;
            j++;

            if (i >= 2000) {

                inspections.pendingInspectionsBatchInsert(batch);                   
                batch.clear();
                i = 0;                  
            }
        }

        if (i > 0) {
            inspections.pendingInspectionsBatchInsert(batch);
            batch.clear();
        }

        br.close();
        file.delete();

    } catch (Exception e) {
        Log.e("SyncActivity", e.toString());            
    }       
}

编辑:这是接口和类声明

public interface Inspectable {
    public int getId();
    public void setId(int id);

    public String getLabel();
    public void setLabel(String label);

    public double getX();
    public void setX(double x);

    public double getY();
    public void setY(double y);
}

public class RWInspection {
private String id;
private double x;
private double y;
private String inspector;
private String comments;
private String timestamp;


public RWInspection(String id, double x, double y, String inspector, String comments, String timestamp) {
        this.id = id;       
        this.x = x;
        this.y = y;
        this.inspector = inspector;
        this.comments = comments;
        this.timestamp = timestamp;
}

snip.... getter 和 setter 实现

public class PInspection implements Inspectable{
    private int id;
    private String number;
    private double x;
    private double y;

public PInspection(int id, String poleNumber, double x, double y) {
    this.id = id;
    this.number = number ;
    this.x = x;
    this.y = y;
}
4

2 回答 2

1

除了对象类之外,它们基本上都是相同的。

听起来您希望为作为批处理过程的一部分创建的所有这些对象提供一个通用接口。我建议如下:

public interface Batchable  {  void doBatch();  }

然后执行以下操作:

public class Foo implements Batchable  {}  
public class Bar implements Batchable {}

您现在可以让每个类实现自己的函数体,doBatch并且您至少部分地抽象出了了解该类的需要。现在就一次持久化 2000 条记录而言,为什么不在大型事务中一次全部推送它们呢?如果不这样做,您将面临数据完整性损失的风险。

于 2012-10-31T16:12:17.080 回答
1

我将其拆分为一个抽象基类和一些实现。基类可能如下所示:

public abstract class Downloader {
    protected abstract void processLine(String[] line);
    protected abstract void save();
    protected abstract String file();
public void downloadPendingPoleInspections() {

    int count;
    String filePath;

    filePath = Environment.getExternalStorageDirectory() + File.separator + file();

    try {

        downloadFile("http://localhost/api/inspectionservices.aspx?o=retrieve", "pending" + file(), POST_PENDING_INSPECTIONS_PROGRESS_UPDATE);

        int totalInspections = getLineCount(filePath);

        File file = new File(filePath);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;

        int i = 0;
        int j = 0;


        while ((line = br.readLine()) != null) {
            processLine(line.split(" "));
            i++;
            j++;

            if (i >= 2000) {
                save()
                i = 0;                  
            }
        }

        if (i > 0) {
            save()
        }

        br.close();
        file.delete();

    } catch (Exception e) {
        Log.e("SyncActivity", e.toString());            
    }       
}

对于您要处理的每种类型,您都可以创建一个像这样的小实现:

public class InspectionDownloader extends DownLoader {
    Inspections inspections = Inspections.getInstance();
    List<PendingInspection> batch = new ArrayList<PendingInspection>();

    public InspectionDownloader() {
        inspections.deleteAllPendingInspections();
    }

    protected void processLine(String[] values) {
        PendingInspection pending = new PendingInspection(
            Integer.parseInt(values[0]), values[1],
            Double.parseDouble(values[2]),
            Double.parseDouble(values[3]));
        batch.add(pending);
    }

    protected void save() {
        inspections.pendingInspectionsBatchInsert(batch);
        batch.clear();
    }
    protected String file() { 
        return "inspections.txt";
    }
}

通过这种方式,可以将可重用逻辑集中在基类中,并将特殊逻辑转移到小型且集中的专用类中。这种模式称为模板化方法。您可以看到派生类非常专注于它所负责的类型的特殊操作。

于 2012-10-31T17:02:40.983 回答