支持 JavaFX + Spring Boot + Hibernate 应用程序中的多个环境



我正在 Spring Boot 中构建一个带有休眠功能的 JavaFX 应用程序。它连接到数据库以显示一些数据,目前它从属性文件中获取连接详细信息,并使用纯 Java 配置加载 sessionFactory、数据源和事务管理器 bean。但是,我在多台远程计算机上有多个数据库,每个数据库都有不同的 IP 和用户详细信息。理想情况下,我想显示一个登录表单,该表单在应用程序启动时提示输入数据库用户名和密码。我不想从文件中读取这些详细信息。可能吗?我真的很感激在这个问题上的一些帮助。

编辑:设法实现这一目标,在我的登录控制器中,我只需实现 ApplicationContextAware,然后使用文本字段中的数据手动加载寄存器豆。

您可以使用 Spring 引导活动配置文件功能

根据您当前的配置文件 PROD、DEV、PRE-PROD,您可以使用给定的 application.properties 文件激活特定配置。您可以在此处找到完整的操作方法

编辑 2 :

如果要根据用户输入(例如凭据(更改整个配置,则必须动态更改属性,并且看起来@RefreshScope完成工作。

坏消息是,这个注释似乎只存在于Spring Cloud中

这是我的解决方案,唯一的缺点是登录尝试失败后我无法登录。它工作正常,但是如果我首先使用不正确的登录凭据,然后更正凭据,它会抛出一个异常,指出EntityManagerFactory已关闭。(我确实删除了 catch 块中的 bean 定义,只是想让代码更短(

@Component
public class LoginController implements Initializable, ApplicationContextAware{
@FXML
private AnchorPane login;
@FXML
private JFXTextField dbUsernameTextField;
@FXML
private JFXPasswordField dbPasswordTextField;
@FXML
private JFXTextField boxUsernameTextField;
@FXML
private JFXPasswordField boxPasswordTextField;
@FXML
private JFXComboBox<ComboItem> environmentComboBox;
@FXML
private JFXButton loginButton;
@Autowired 
private Environment environment;
@Autowired
private OrderService orderService;
private AnnotationConfigApplicationContext context;
@Override
public void initialize(URL location, ResourceBundle resources) {
loginButton.setDisable(true);
List<ComboItem> envs=new ArrayList<ComboItem>();
String[]environments=environment.getProperty("environments").split(",");
for(String s:environments) {
environmentComboBox.getItems().add(new ComboItem(s.toUpperCase(),s));
}
environmentComboBox.setConverter(new StringConverter<ComboItem>() {
@Override
public String toString(ComboItem object) {
return object.getKey();
}
@Override
public ComboItem fromString(String string) {
return null;
}
});
}
@FXML
public void selectEnvironment() {
if(!environmentComboBox.getSelectionModel().isEmpty())
loginButton.setDisable(false);
}
@FXML
public void authenticate(ActionEvent actionEvent) {
String boxUsername=boxUsernameTextField.getText();
String boxPassword=boxPasswordTextField.getText();
try {
context.registerBean("dataSource",DataSource.class,()->dataSource());
context.registerBean("sessionFactory", LocalSessionFactoryBean.class,()->sessionFactory());     
context.registerBean("transactionManager",HibernateTransactionManager.class,()->getTransactionManager());
Order order=orderService.findById("");
FXMLLoader fxmlLoader=new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
fxmlLoader.setControllerFactory(context::getBean);
Parent rootNode=fxmlLoader.load();
Stage stage=(Stage) login.getScene().getWindow();
Scene scene=new Scene(rootNode,400,300);
stage.setScene(scene);
stage.setTitle("Login");
stage.setMaximized(true);
stage.show();
stage.setOnCloseRequest(event->JSchConnection.close());
}catch(Exception e) {
context.removeBeanDefinition("dataSource");
context.removeBeanDefinition("sessionFactory");
context.removeBeanDefinition("transactionManager");
e.printStackTrace();
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context=(AnnotationConfigApplicationContext) applicationContext;       
}
private  Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");
properties.put("hibernate.show_sql", "false");
properties.put("hibernate.format_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "none");
return properties;
}
public  DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.OracleDriver");
dataSource.setUrl("myurl");
dataSource.setUsername(dbUsernameTextField.getText());
dataSource.setPassword(dbPasswordTextField.getText());
return dataSource;
}
public  LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.mypackage" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
public HibernateTransactionManager getTransactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(context.getBean(SessionFactory.class,"sessionFactory"));
return transactionManager;
}
}

最新更新