1

我必须解析 JSON 文件中的数据并将数据插入到我的数据库中。共有三个文件:

  • 国家

    [ { "id": 1, "name": "美国", "org_ids": [ 1, 2, 3 ] }, { "id": 2, "name": "中国", "org_ids": [ 1, 3, 4 ] }, { "id": 3, "name": "Hong Kong", "org_ids": [ 1, 2 ] } ]

  • 国际组织

    [ { "id": 1, "name": "UNO" }, { "id": 2, "name": "美洲国家组织" }, { "id": 3, "name": "INTERPOL" }, { "id": 4, "name": "欧盟" }, { "id": 5, "name": "英联邦" } ]

  • 大陆

    [ {“id”:1,“name”:“非洲”},{“id”:2,“name”:“北美”},{“id”:3,“name”:“南美”} , { "id": 4, "name": "Asia" }, { "id": 5, "name": "Europe" }, { "id": 6, "name": "Australia" } ]

请不要关注我的 JSON 的内容,它们不包含所列国际组织的真实成员。这只是一个例子。

在这里,我被建议使用访问者设计模式。我完全同意使用它,以免将 JSON 读取逻辑与数据库逻辑混为一谈。

我的 JSON 解析器类如下。

class JsonParser {

    private List<Country> mCountries;

    private abstract class BaseEntity {

        private String name;
        private long id;

        private BaseEntity(long id, String name) {
            this.id = id;
            this.name = name;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return ID + COLON + SPACE + id + COMMA + SPACE + NAME + COLON + SPACE + name;
        }
    }

    class Country extends BaseEntity {

        private List<Long> orgsIds;

        public Country(long id, String name, List<Long> orgsIds) {
            super(id, name);
            this.orgsIds = new ArrayList<Long>();
            this.orgsIds.addAll(orgsIds);
        }

        public List<Long> getOrgsIds() {
            return orgsIds;
        }

        @Override
        public String toString() {
            return super.toString() + COMMA + SPACE + ORG_IDS + SPACE + orgsIds;
        }

    }
}

现在我不明白如何将访问者模式应用于集合 mCountries。我打算用类bulkInsert方法插入整个列表,ContentProvider因为它比insert.

我需要一个优雅的解决方案。

4

1 回答 1

0

解决方案。

我自己找到了解决方案。我不需要访客模式。我刚刚实现了以下逻辑。

JsonPasrer。

此类仅从 JSON 文件中读取数据。

public class JsoinParser {

    /**
     * Reads a JSON file to a string
     * 
     * @param fileName JSON file name
     * @return null if reading failed
     */
    private String readToString(String fileName) throws IOException {
        StringBuilder resultBuilder = new StringBuilder();
        String filePath = mContext.getExternalFilesDir(null).getAbsolutePath() + File.separatorChar + fileName;
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new FileReader(filePath));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                resultBuilder.append(line);
            }
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    Log.e("%s", "Failed to close the BufferedReader instance");
                }
            }
        }
        return resultBuilder.toString();

    }

    public List<Organization> readOrgs() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.ORGS));
        List<Organization> list = new ArrayList<JsonParser.Organization>();
        // TODO: read here and fill
        return list;
    }

    public List<Continent> readContinents() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.CONTINENTS));
        List<Continent> list = new ArrayList<JsonParser.Continent>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            list.add(new Continent(object.getLong(ID), object.getString(NAME)));
        }
        return list;
    }

    public List<Country> readCountries() throws JSONException, IOException {
        JSONArray array = new JSONArray(readToString(FilesNames.COUNTRIES));
        List<Country> list = new ArrayList<JsonParser.Country>();
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            long id = object.getLong(ID);
            String name = object.getString(NAME);
            List<Long> orgsIds = new ArrayList<Long>();
            try {
                JSONArray orgs = object.getJSONArray(ORGS_IDS);
                orgsIds = new ArrayList<Long>();
                for (int j = 0; j < orgs.length(); j++) {
                    orgsIds.add(orgs.getLong(j));
                }
            } catch (JSONException e) {
                Log.v("%s", name + " is not a member of any international organizations");
            }

            long continentId = object.getLong(CONTINENT_ID);
            list.add(new Country(id, name, orgsIds, continentId));
        }
        return list;
    }

    /**
     * Common base class for all the entities read from JSON file. The entities are {@link Country},
     * {@link Organization}, and {@link Continent}
     * 
     * @author Red Planet
     * 
     */
    abstract class BaseEntity {

        String name;
        long id;
        List<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

        private BaseEntity(long id, String name) {
            this.id = id;
            this.name = name;
        }

        public long getId() {
            return id;
        }

        // Insert all the data within a transaction
        abstract public List<ContentProviderOperation> getOperations();

        public String getName() {
            return name;
        }
    }

    public class Country extends BaseEntity {

        private List<Long> orgsIds;
        private long continentId;

        public Country(long id, String name, List<Long> orgsIds, long continentId) {
            super(id, name);
            this.orgsIds = new ArrayList<Long>();
            this.orgsIds.addAll(orgsIds);
            this.continentId = continentId;
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }

    }

    public class Organization extends BaseEntity {

        private Organization(long id, String name) {
            super(id, name);
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }
    }

    public class Continent extends BaseEntity {

        private Continent(long id, String name) {
            super(id, name);
        }

        @Override
        public List<ContentProviderOperation> getOperations() {
            ContentValues values = new ContentValues();
            // TODO: fill ContentValues with the data which will be inserted
            return operations;
        }
    }
}

JsonParserHelper。

此类获取由readX方法填充的数组并填充我的数据库。

public class JsonParserHelper {

    public void insert(Context context, List<? extends BaseEntity> entities)
            throws OperationApplicationException, RemoteException {
        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
        for (BaseEntity entity : entities) {
            operations.addAll(entity.getOperations());
        }
        context.getContentResolver().applyBatch(DatabaseProvider.AUTHORITY, operations);
    }

}
于 2013-05-20T11:56:06.417 回答