Nano Hash - криптовалюты, майнинг, программирование

Порядок инициализации контроллера JavaFx — база данных вызывается несколько раз

У меня есть стандартное приложение JavaFX, которое расширяет Application. Первая страница, которую я показываю, — это панель инструментов с кнопками для открытия других приложений. Это все в порядке, первое приложение — это страница администратора под названием AdminController, которая позволяет пользователю выполнять операции CRUD над объектами модели — пользователем, контактами, продуктами, каждая сущность — это вкладка в представлении администратора — так что в моем основном Admin FXML (используя SceneBuilder ) Я включаю другие страницы fxml, используя fx:include вкладку пользователей, вкладку контактов и вкладку продуктов. Опять же, все эти включения находятся в файле Admin.fxml с собственным контроллером.

<Tab fx:id="contactsTab" onSelectionChanged="#goToContacts" text="Contact">
   <content>
     <fx:include source="/fxml/manager_contacts_tab.fxml" fx:id="contact" />
   </content
<Tab/>

Моя идея заключалась в том, чтобы загрузить ресурсы, которые потребуются каждой странице, пользователей/контакты/продукты в AdminController, чтобы каждый fx:include, который я использовал, мог использовать те же самые объекты. Поскольку некоторым вкладкам нужны все эти ресурсы, например пользователям, для управления ассоциациями, а другим вкладкам, таким как продукт, нужен только список продуктов. Мой основной контроллер выглядит так.

public class AdminController {
  @FXML
  UserController userController;
  @FXML
  ProductController productController;
  @FXML
  ContactController contactController;

@FXML
public void initialize
    // at this point userController already ran, and called DB so it calls it again here
    if (users == null) {
        this.users = FXCollections.observableArrayList(userDao.getAllWithProductsAndContacts());
    }
    if (products == null) {
        this.products = FXCollections.observableArrayList(productDao.getAll());
    }
    if (contacts == null) {
        this.contacts = FXCollections.observableArrayList(contactDao.getAll());
    }
    contactController.setContacts(contact);
    // set other resources, like products
}

Логически в моей голове я бы подумал, что метод инициализации для AdminController будет запущен первым, что позволит мне установить любые объекты, которые мне нужны, в дочерних контроллерах, поскольку я могу получить к ним доступ, но происходит то, что дочерние контроллеры запускаются первыми, например . с контактконтроллером

public class ContactController {
    @FXML
    public void initialize() {
        if (contacts == null) {
            this.contacts = FXCollections.observableArrayList(contactDao.getAll());
        }
    }

Таким образом, мои приложения инициализируют методы, запускаемые в том порядке, в котором они были включены в admin.fxml userController, contactController, наконец, productController.

Я думаю, что мой вопрос сводится к тому, как я могу обмениваться объектами между дочерними контроллерами, чтобы при нажатии на новую вкладку с тем же списком ресурсов, что и на предыдущей, новый вызов базы данных не инициировался - в моем примере это происходит, когда Я загружаю пользовательскую страницу, ей нужен список контактов и список продуктов, но ContactController и ProductController нужны те же самые списки, и не должно быть необходимости делать еще один вызов БД.


  • Мне не на 100% ясно, что именно вы здесь спрашиваете. Что вы подразумеваете под обращением к базе данных? Обычно вы только запрашиваете БД (если вы ее не изменяете), и для ее завершения требуется только мс. В противном случае (если база данных достаточно мала) вы можете загрузить ее в память при запуске вашей программы и вообще не получать ее в своих контроллерах. Под базой данных вы подразумеваете набор файлов, которые вы сериализовали, или вы говорите о базе данных SQL? 13.07.2017
  • Что я обычно делаю с небольшим хранилищем, так это определяю класс с именем Data и храню в нем ArrayLists, которые содержат объекты базы данных (такие как пользователи, продукты и т. д.). Я загружаю эти ArrayLists при запуске моей программы. Таким образом, ваши контроллеры могут просто вызывать что-то вроде Data.getContacts(); захватить все контакты. Если мы говорим об огромной базе данных, то для получения информации следует запускать SQL-запросы. 13.07.2017
  • Извините, должен был уточнить - это база данных SQL, я думаю, что мой вопрос заключается в том, где сначала сделать вызов в базу данных, чтобы получить список элементов, с которыми я работаю - моя первая мысль заключалась в том, чтобы сделать все вызовы базы данных в AdminController для установки дочерние контроллеры, но дочерние контроллеры инициализируются до AdminController, поэтому в этот момент должен быть сделан вызов, а дочерние контроллеры, которые совместно используют один и тот же список данных, не видны друг другу, например, контроллеры контактов/администрирования - ContactController нужны контакты, но то же самое делает UserController (чтобы показать ассоциации между ними). 13.07.2017

Ответы:


1

В вашем случае, если вы загружаете «все» контакты сразу, я, вероятно, сделаю вызов базы данных ДО того, как вы инициализируете один контроллер.

package main;

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {

    public void start(Stage window) throws Exception {
        // Database call goes here!
        DatabaseManager.initialize();


        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        // Whatever window initialization stuff you need to do
        window.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

Теперь для вашего класса DatabaseManager

package sample;

public class DatabaseManager {

    public static void initialize() {
        // Query the database for your information.
        // Little pseudo code here
        Data.setUsers(Database.userQuery);
        Data.setContacts(Database.contactQuery);
        Data.setProducts(Database.productQuery);
    }

}

Теперь класс данных

package sample;

public class Data {

    public static ArrayList<User> getUsers() {
        return users;
    }

    public static void setUsers(ArrayList<User> users) {
        this.users = users;
    }

    public static ArrayList<Contact> getContacts() {
        return contacts;
    }

    public static void setContacts(ArrayList<Contact> contacts) {
        this.contacts = contacts;
    }

    public static ArrayList<Product> getProducts() {
        return products;
    }

    public static void setProducts(ArrayList<Product> products) {
        this.products = products;
    }

    private static ArrayList<User> users = new ArrayList<User>();
    private static ArrayList<Contact> contacts = new ArrayList<Contact>();
    private static ArrayList<Product> products = new ArrayList<Product>();

}

Теперь вашим контроллерам нужно только позвонить

this.contacts = FXCollections.observableArrayList(Data.getContacts());

и это подготовит ваш список контактов к работе.

Также обратите внимание, что это то, что называется «загрузкой в ​​память». Другими словами, вы храните всю эту информацию в памяти компьютера и получаете к ней доступ оттуда. Это НЕ будет работать для ОГРОМНОЙ базы данных, потому что у вашего компьютера просто не будет места для мозгов. В любом случае, надеюсь, это поможет.

13.07.2017
  • Благодарю вас! Прямо сейчас мое приложение достаточно маленькое, чтобы это сработало - однако план состоит в том, что оно вырастет в большое приложение, есть ли у вас какие-либо предложения по более крупным приложениям? В идеале я хотел бы загружать его только при необходимости, но инициализация контроллера @FXML сбивает меня с толку и работает не в том порядке, в котором я ожидал. Мои ожидания, где -> AdminController — загрузить то, что необходимо для представлений, чтобы представления, относящиеся к этому контроллеру, т. е. ContactController, могли иметь доступ к контактам AdminControllers — сначала инициализируется только ContactController. 13.07.2017
  • Ну, если честно, мне никогда не нравился метод инициализации контроллеров. Для меня это тоже было немного шатко. Я не уверен, как работает ваша программа, но для меня то, что я сделал во всех своих проектах FX, - это создать класс контроллера и расширить все мои другие контроллеры из этого класса, и у меня есть публичный метод start(), который я создал себя в этом родительском классе, и всякий раз, когда я загружаю контроллер, я вызываю метод start(). Все расширенные контроллеры переопределяют метод start(). 14.07.2017
  • Спасибо, Филипп, я ценю ответы - я еще немного поиграю с этим и посмотрю, что я могу придумать. 14.07.2017
  • Повозился с ним еще немного, и зачем беспокоиться, я пошел с вашим абстрактным контроллером, и он решает мою проблему, ура. 14.07.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..