首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何用.json文件刷新一个基本的“数据库”

如何用.json文件刷新一个基本的“数据库”
EN

Stack Overflow用户
提问于 2018-06-05 06:10:09
回答 1查看 30关注 0票数 0

我正在做一个用Java写的大学项目。这个项目是为一家体育用品连锁店开发的一个小软件。我的老师告诉我要保存员工信息,运动物品和许多其他东西(商店订单,...)转换成JSON文件,使用JSON simple.jar。我的软件一开始就从.json文件中加载列表,下面是一个例子:

代码语言:javascript
复制
private static ArrayList<Person> personale = new ArrayList<Person>();
public ArrayList<Person> readPersonale() throws IOException, org.json.simple.parser.ParseException {
    JSONParser parser = new JSONParser();
    FileReader fileReader = new FileReader("f:\\personale.json");
    JSONObject jsonObject = (JSONObject) parser.parse(fileReader);
    ArrayList<Person> personale = new ArrayList<>();
    JSONArray array = (JSONArray) jsonObject.get("personale");
    for(int i=0; i<array.size(); i++) {
        Person p = new Person();
        JSONObject json = (JSONObject)array.get(i);
        p.setName(json.get("NAME"));
        p.setSurname(json.get("SURNAME"));
        p.setUserCode(json.get("USER CODE"));
        p.setPassword(json.get("PASSWORD"));
        p.setRule(json.get("RULE"));
        personale.add(p);
    }
    fileReader.close();
    return personale;
}

在软件关闭之前,我的程序必须删除以前.json文件的内容,并将所有列表重写到同一个.json文件中:

代码语言:javascript
复制
    public void writePersonale(ArrayList<Person> list) throws org.json.simple.parser.ParseException, ParseException {

    JSONObject obj = new JSONObject();
    JSONArray Jlist = new JSONArray();
    for(Person e : list) {
        JSONObject json = new JSONObject();
        json.put("NAME", e.getName());
        json.put("SURNAME", e.getSurname());
        json.put("USER CODE", e.getUserCode());
        json.put("PASSWORD", e.getPassword());
        json.put("RULE", e.getRule());
        Jlist.add(json);
    }
    obj.put("personale", Jlist);

    try (FileWriter file = new FileWriter("f:\\personale.json")) {
        file.write(obj.toJSONString());
        file.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

这是用.json文件编程的正确方式吗?有没有更好的方法来使用jSON文件?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-05 07:03:27

好的,首先,我将避免使用您正在用于JSON处理的库。手动创建JSONArrays等更多的是一种痛苦,而不是一些富有成效的事情。从这个意义上说,我会使用Jackson来执行任何序列化/反序列化(向db写入和从db写入)。

由于Jackson可以主动映射数据类型并转换它们,因此您将使用以下POJO来完成您的工作:

UserDto

代码语言:javascript
复制
public class UserDto {

    private String name;
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    private String surName;
    public String getSurName() { return surName; }
    public void setSurName(String surName) { this.surName = surName; }

    private Integer userCode;
    public Integer getUserCode() { return userCode; }
    public void setUserCode(Integer userCode) { this.userCode = userCode; }

    private String rule;
    public String getRule() { return rule; }
    public void setRule(String rule) { this.rule = rule; }

    public UserDto() {}

    public UserDto(String name, String surName, Integer userCode, String rule) {
        this.name = name;
        this.surName = surName;
        this.userCode = userCode;
        this.rule = rule;
    }

    @Override
    public String toString() {
        return "UserDto{" +
            "name='" + name + '\'' +
            ", surName='" + surName + '\'' +
            ", userCode=" + userCode +
            ", rule='" + rule + '\'' +
            '}';
    }

}

BulkUserDto

代码语言:javascript
复制
public class BulkUserDto {

    private List<UserDto> userDtos;
    public List<UserDto> getUserDtos() { return userDtos; }
    public void setUserDtos(List<UserDto> userDtos) { this.userDtos = userDtos; }

}

有了这两个工具,您的数据库实用程序类就可以简化为:

代码语言:javascript
复制
public final class DatabaseUtil {

    private static final String FILE_PATH = "/tmp/db.json";

    private static ObjectMapper objectMapper = new ObjectMapper();

    private DatabaseUtil() {}

    public static List<UserDto> initUserList() throws IOException {
        BulkUserDto dto = objectMapper.readValue(Paths.get(FILE_PATH).toFile(), BulkUserDto.class);
        return dto.getUserDtos();
    }

    public static void saveUserList(BulkUserDto dto) throws IOException {
        String parsedObject = objectMapper.writeValueAsString(dto);
        if (Files.exists(Paths.get(FILE_PATH))) {
            System.out.println("Found old db file under:: " + FILE_PATH + " deleting");
            Files.delete(Paths.get(FILE_PATH));
        }

        FileWriter writer = new FileWriter(Paths.get(FILE_PATH).toFile());
        writer.write(parsedObject);
        writer.flush();
    }

}

请注意,序列化/反序列化过程是如何简化的。有关杰克逊的更多信息,您可以参考以下基本教程https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/

另请注意,如果旧的db.json文件已经存在于文件系统中,则保存方法会主动检查并删除该文件。

您可以进行的另一个很好的优化是以下内容。由于您将所有读取的用户条目存储在一个静态列表中,因此您实际上是在创建一个缓存。我假设您只通过程序调用readPersonale一次,否则,由于您似乎没有相关的检查到位,这将破坏它。基于上述情况,我将提出以下建议:

我会让静态列表声明保持不变,但是我不会给它分配一个空的列表,而是让它保持为空。然后,我将创建以下方法,以确保缓存只初始化一次:

代码语言:javascript
复制
private static final Object LOCK = new Object();
    private static List<UserDto> userCache;
    public static List<UserDto> getUserCache() {
        synchronized (LOCK) {
            if (userCache == null) {
                try {
                    userCache = initUserList();
                } catch (IOException e) {
                    return Collections.emptyList();
                }
            }
            return userCache;
        }
    }

注意这里的synchronized块,它将确保初始化只发生一次,并且只由第一个调用线程发生。

有了它,我将简单地使用这个缓存来添加/删除用户,最后我将继续保存它。请注意,如果您选择遵循这一点,则应该考虑同步(假设您的程序中有多个线程)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50689464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档