当我意识到数据库位置硬编码到PU中时,我正在使用UCanAccess并设置实体和持久化单元。xml(可以构建实体,但我需要变量)。
我正在创建一个应用程序,将提供给需要访问自己数据库的人,但这是一个随机路径。
我很好奇我到底如何才能更改PU中的信息?
我能想到的唯一方法是如何编辑xml文件,或者动态创建xml文件。
有人知道我是怎么做到的吗?
使用常规java.sql命令很简单,所以我希望它在JPA中也能轻松工作。
谢谢大家!
您可以通过传入属性对象来设置动态EntityManagerFactory
,如下所示:
Persistence.createEntityManagerFactory("unit-name", properties);
你可以查看我关于类似问题的更详细答案:
EclipseLink JPA 2.1用户提供的连接
如果您想使用具有持久性的“标准”JPA,那么可能是不可能的。xml。
然而,如果您的应用程序是在Spring之上构建的,那么只需将正确的值注入到LocalEntityManagerFactoryBean(数据源、方言等),一切都应该正常。
请注意,应用程序应避免使用本机SQL,因为在大多数情况下,本机SQL是不可移植的。
这可以通过利用到将使用连接池的数据源的数据库连接属性(凭据等)来实现。您可以通过3种方式提供数据源:
>
直接在XML文件中。JPA将尝试从JNDI获取数据源。这在JBoss/Wildfly或GlassFish等应用程序服务器中工作时很有用,甚至在Tomcat等servlet容器中也很有用。这种方法的缺点是这不容易在JavaSE环境中复制,基本上是因为您必须提供JNDI提供程序以及这意味着的所有内容。您的persistence.xml如下所示:
<persistence-unit name="foo-PU" transaction-type="RESOURCE_LOCAL">
<!-- the provider: Hibernate, EclipseLink or another -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- JNDI name of your datasource -->
<non-jta-data-source>jdbc/myds</non-jta-data-source>
<!-- class definitions here -->
<!-- if working with hibernate, you should provide the dialect -->
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
</properties>
</persistence-unit>
在创建EntityManagerFactory时,以编程方式提供数据库连接属性。注意,这种方法在很大程度上取决于JPA供应商。这是在EclipseLink中实现的方法(来自http://eclipse.1072660.n5.nabble.com/Defining-persistence-xml-programatically-td2536.html):
import static org.eclipse.persistence.jpa.config.PersistenceUnitProperties.*;
Map properties = new HashMap();
// Configure the internal EclipseLink connection pool
properties.put(JDBC_DRIVER, "oracle.jdbc.OracleDriver");
properties.put(JDBC_URL, "jdbc:oracle:thin:@localhost:1521:ORCL");
properties.put(JDBC_USER, "user-name");
properties.put(JDBC_PASSWORD, "password");
Persistence.createEntityManagerFactory("unit-name", properties);
就个人而言,这看起来非常丑陋和令人不快,特别是因为JPA供应商在创建实体管理器(EntityManager)时会创建物理连接。这就是为什么我建议将数据库属性包装到像C3P0或BoneCP这样的数据源中。在本例中,我使用BoneCP以编程方式设置数据源(因此重点是设置单个属性),然后将其作为属性传递以创建EntityManagerFactory(这是我在生产中使用的真实代码的基本改编,因此请原谅糟糕的设计=\):
persistence.xml:
<persistence-unit name="foo-PU" transaction-type="RESOURCE_LOCAL">
<!-- the provider: Hibernate, EclipseLink or another -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- class definitions here -->
</persistence-unit>
有两种方法:一种是创建数据源,另一种是创建EntityManagerFactory。
public final class EntityManagerFactoryCreator {
private static DataSource getDataSource(String properties) {
Properties conf = new Properties();
try {
conf.load(
DataSourceFactory.class
.getClassLoader().getResourceAsStream(
properties));
} catch (IOException e) {
//handle the error
//naive handling shown here
e.printStacktrace();
}
BoneCPDataSource dataSource = new BoneCPDataSource();
dataSource.setDriverClass(conf.getProperty("db.driver"));
dataSource.setJdbcUrl(conf.getProperty("db.url"));
dataSource.setUsername(conf.getProperty("db.user"));
dataSource.setPassword(conf.getProperty("db.password"));
dataSource.setIdleConnectionTestPeriodInMinutes(
Long.parseLong(
conf.getProperty("db.bonecp.idleConnectionTestPeriod")));
dataSource.setIdleMaxAgeInSeconds(
Long.parseLong(
conf.getProperty("db.bonecp.idleMaxAge")));
dataSource.setMaxConnectionsPerPartition(
Integer.parseInt(
conf.getProperty("db.bonecp.maxConnections")));
//more properties to load...
return dataSource;
}
public static EntityManagerFactory createEMF() {
Map<String, Object> properties = new HashMap<>();
String dataSourceKey = "";
//using Hibernate
//dataSourceKey = org.hibernate.cfg.AvailableSettings.DATASOURCE;
//using EclipseLink
//dataSourceKey = org.eclipse.persistence
// .config.PersistenceUnitProperties.NON_JTA_DATASOURCE;
properties.put(
dataSourceKey,
getDataSource("mysql-con.properties"));
return Persistence.createEntityManagerFactory("foo-PU", properties);
}
}
包含连接属性的mysql-con.properties
配置文件:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/foo_db
db.user=user
db.password=s3cr3t
db.bonecp.idleConnectionTestPeriod=60
db.bonecp.idleMaxAge=240
db.bonecp.maxConnections=10
# more properties...
上面的代码可以在Java SE和Java EE环境中工作,您不需要为其提供JNDI数据源,并且可以进行增强以支持指向更多数据库的不同数据源(只需根据您的数据库配置创建更多属性文件并重用代码)。缺点是它与JPA供应商紧密耦合,如变量值所示。
使用Spring或CDI等依赖注入框架,它可以帮助您为EntityManagerFactory
提供数据源。我无法为这种方法提供开箱即用的解决方案,因为我还没有测试过它(尚未),但网上有很多教程。
根据您的项目需求选择最佳选项。
问题内容: 我想用MySQL和JPA设置Spring Boot。为此,我创建: Person PersonRepository PersonController 开始课程示例: 对于数据库配置,我创建了application.properties 所以我有项目结构: 但是结果是我有例外: 问题答案: 我像你一样创建了一个项目。结构看起来像这样 这些类只是复制自你的类。 我将application.
问题内容: 是否可以使用Firefox插件创建Selenium测试,该插件使用随机生成的值来帮助进行回归测试? 全文: 我想通过为客户提供一套使用某些智能工具为数据库创建随机(或至少伪随机)值的测试来帮助他们进行验收测试。目前,我的Selenium IDE测试的问题之一是它们具有预定义的值-这使某些类型的测试成为问题。 问题答案: 首先,Selenium IDE相当有限,您应该考虑切换到Selen
我试图在我的codeigniter应用程序中包含甘特图。接下来的教程一是:https://docs.dhtmlx.com/tutorials__connector_codeigniter__step6.html 当我深入研究这个问题并直接点击控制器时,我发现了一个问题: Sub_文件夹是实际的项目文件夹,其中有复制粘贴dhtmlx、dhtmlxGantt和dhtmlxScheduler文件夹。我不
我正在创建一个Android库(.aar文件),我需要使用JNI。(如果可能的话,我很清楚谷歌不鼓励使用JNI/NDK,但在这种情况下,这是不可能的)。 我从一个独立的hello jni示例应用程序开始(首先学习jni),其中包含以下文件: HelloJni.java Android.mk 应用程序.mk 你好,jni.c 以下构建良好的应用程序(apk),我能够在我的设备上运行它,它打印“Hel
使用React-Native并尝试学习ES6语法。我昨天也遇到了类似的问题,并得到了解决方案。我补充说 .绑定(这个) 到我的我的函数调用和问题解决。我在另一个函数调用中再次遇到了同样的问题,我无法跟踪到底发生了什么。错误消息是相同的。
问题内容: 我是Spring的新手。 我们正在使用Spring Security功能。数据库连接:JPA的eclipselink实现。数据库:MySql 使用spring security时,身份验证提供程序的配置如下- 但是在JPA中,我们没有定义数据源,我们将Persistence unit与provider一起使用 那么,我们如何配置身份验证提供程序,以便将JPA用于数据库连接? 数据源引用