Хорошо, во-первых, я бы избегал использования библиотеки, которую вы используете для обработки JSON.Ручное создание JSONArrays и т. Д. - скорее боль в заднице, чем продуктивная работа.В этом смысле я бы пошел с Jackson
, чтобы выполнить любую сериализацию / десериализацию (запись в и из БД).
Поскольку Jackson
может активно отображать типы данных и конвертировать их, вы будете использовать следующие POJO для выполнения вашихзадание:
UserDto
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
public class BulkUserDto {
private List<UserDto> userDtos;
public List<UserDto> getUserDtos() { return userDtos; }
public void setUserDtos(List<UserDto> userDtos) { this.userDtos = userDtos; }
}
С этими двумя возможностями ваш служебный класс базы данных можно упростить до следующего:
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
через программу только один раз, и, поскольку кажется, что у вас нет связанных проверок, это может привести к его повреждению.Исходя из вышеизложенного, я бы предложил следующее:
Я бы оставил объявление статического списка, но вместо того, чтобы назначить ему пустой список, я бы пошел дальше и оставил его пустым.Затем я бы создал следующий метод, чтобы убедиться, что кеш инициализируется только один раз:
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;
}
}
Обратите внимание на синхронизированный блок, который будет гарантировать, что инициализация произойдет только один раз и только первым вызывающим потоком.
Имея это, я бы просто использовал этот кеш для добавления / удаления пользователя, а затем, наконец, просто сохранил это.Обратите внимание, что если вы решите следовать этому, вы должны принять во внимание синхронизацию (при условии, что в вашей программе более одного потока).