可以配置Hibernate来使用javax.sql.DataSource示例吗?我的应用程序已经有了一个javax.sql.DataSource的示例,我不想仅仅为了休眠而重新配置数据库URL、用户、密码、驱动程序等。
n53p2ov01#
如果数据源可以通过JNDI获得,那么您只需要设置配置的hibernate.connection. configuration属性- mtpettyp的答案说明了这一点。如果您所处的环境中的数据源不是来自JNDI,请提供您自己的ConnectionProvider实现,并在构建会话工厂之前将其传递给Settings对象,或者在hibernate.connection.provider_class属性中指定其类名。如果您为Settings提供了一个示例,那么您可能可以示例化标准DatasourceConnectionProvider并给予您的DataSource。
frebpwbc2#
在您的hibernate.cfg.xml中:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="connection.datasource">SampleDS</property> </session-factory> </hibernate-configuration>
xurqigkl3#
如果您使用Spring初始化和Spring会话工厂Bean,则可以像这样简单地传入数据源
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> ... </bean>
其中dataSource引用在别处定义。
4uqofj5v4#
我找不到一个完整的例子来说明如何使用现有的DataSource示例仅通过代码(没有XML文件,没有JNDI)配置Hibernate/Jakarta Persistence。所以我把这个贴在这里。希望它能帮助其他人。下面是一个使用Java SE的示例,没有任何Jakarta EE应用服务器。我用的是:
DataSource
👉🏼 我用下面的代码严格配置了Hibernate。我没有写任何配置XML文件。
javax.sql.DataSource与Java SE捆绑在一起。我们需要一个接口的实现。在本例中,我们使用com.mysql.cj.jdbc.MysqlDataSource类中JDBC驱动程序 MySQL Connector/J 提供的实现。我们在下面的方法中设置了DataSource实现的一个示例。
javax.sql.DataSource
com.mysql.cj.jdbc.MysqlDataSource
private DataSource configureDataSource ( ) { com.mysql.cj.jdbc.MysqlDataSource dataSource = new com.mysql.cj.jdbc.MysqlDataSource ( ); dataSource.setDatabaseName ( "bogus_" ); dataSource.setServerName ( "localhost" ); dataSource.setPort ( 8090 ); dataSource.setUser ( "root" ); dataSource.setPassword ( "" ); // WARNING: Risky business, leaving your server unprotected, without security. return dataSource; }
有关详细信息,请参阅 Connector/J 手册的Configuration Properties。
有了这个DataSource示例,我们可以使用Hibernate连接到数据库服务器,执行查询,并将检索到的数据打包为对象。
Configuration cfg = new Configuration ( ); cfg.getProperties ( ).put ( Environment.DATASOURCE , this.dataSource ); cfg.addAnnotatedClass ( Book.class ); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder ( ).applySettings ( cfg.getProperties ( ) ).build ( ); try ( SessionFactory sessionFactory = cfg.buildSessionFactory ( serviceRegistry ) ) { Session session = sessionFactory.openSession ( ); Query jpqlQuery = session.createQuery ( "SELECT b FROM Book b WHERE b.title=:title" , Book.class ); jpqlQuery.setParameter ( "title" , "Our First Book" ); Book book = ( Book ) jpqlQuery.getSingleResult ( ); System.out.println ( "Retrieved via Hibernate… book = " + book ); }
Book = Book{id=1,title ='我们的第一本书',createdOn=2023-08- 14 T20:26:20.708102Z}
Book类我们期望Hibernate示例化这个类的对象。
Book
package work.basil.example.hibernate; import jakarta.persistence.* ; import java.time.OffsetDateTime; @Entity @Table(name = "book") public class Book { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; private String title; @Column(name = "created_on") private OffsetDateTime createdOn; // Accessors public Long getId ( ) { return id; } public void setId ( Long id ) { this.id = id; } public String getTitle ( ) { return title; } public void setTitle ( String title ) { this.title = title; } public OffsetDateTime getCreatedOn ( ) { return createdOn; } public void setCreatedOn ( OffsetDateTime createdOn ) { this.createdOn = createdOn; } // Object overrides @Override public String toString ( ) { return "Book{" + "id=" + id + ", title='" + title + '\'' + ", createdOn=" + createdOn + '}'; } }
以及我们完整的示例应用程序代码。代码:1.重新创建一个表book。然后用单行重新填充该表。这两个步骤都直接使用JDBC,而不是Hibernate。1.使用Hibernate查询单行,并使用检索到的数据示例化Book对象。
book
package work.basil.example.hibernate; import jakarta.persistence.*; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.Session; import org.hibernate.cfg.Environment; import org.hibernate.service.ServiceRegistry; import javax.sql.DataSource; import java.sql.*; import java.time.Instant; import java.time.OffsetDateTime; import java.time.*; import java.time.ZonedDateTime; public class App { final DataSource dataSource; private void demo ( ) { this.dropTable ( ); this.createTable ( ); this.insertRow ( ); this.dumpRows ( ); this.dumpHibernate ( ); } private void dumpHibernate ( ) { Configuration cfg = new Configuration ( ); cfg.getProperties ( ).put ( Environment.DATASOURCE , this.dataSource ); cfg.addAnnotatedClass ( Book.class ); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder ( ).applySettings ( cfg.getProperties ( ) ).build ( ); try ( SessionFactory sessionFactory = cfg.buildSessionFactory ( serviceRegistry ) ) { Session session = sessionFactory.openSession ( ); Query jpqlQuery = session.createQuery ( "SELECT b FROM Book b WHERE b.title=:title" , Book.class ); jpqlQuery.setParameter ( "title" , "Our First Book" ); Book book = ( Book ) jpqlQuery.getSingleResult ( ); System.out.println ( "Retrieved via Hibernate… book = " + book ); } } private void dumpRows ( ) { String sql = """ SELECT * FROM book ; """; try ( Connection connection = this.dataSource.getConnection ( ) ; Statement statement = connection.createStatement ( ) ; ResultSet resultSet = statement.executeQuery ( sql ) ; ) { record BookRecord( Long id , String title , OffsetDateTime odt ) { } while ( resultSet.next ( ) ) { Long id = resultSet.getLong ( "id" ); String title = resultSet.getString ( "title" ); OffsetDateTime odt = resultSet.getObject ( "created_on" , OffsetDateTime.class ); System.out.println ( new BookRecord ( id , title , odt ).toString ( ) ); } } catch ( SQLException e ) { throw new RuntimeException ( e ); } } private void insertRow ( ) { String sql = """ INSERT INTO book ( title , created_on ) VALUES ( ? , ? ) ; """; try ( Connection connection = this.dataSource.getConnection ( ) ; PreparedStatement preparedStatement = connection.prepareStatement ( sql ) ; ) { ZonedDateTime zdt = ZonedDateTime.now ( ZoneId.of ( "America/Edmonton" ) ); // Capture the current moment as seen in a particular time zone. OffsetDateTime odt = zdt.toOffsetDateTime ( ); // Discard the time zone, keeping only a mere offset-from-UTC. Not an improvement, but standard SQL does not support only offsets, not time zones. Instant instant = odt.toInstant ( ); // Adjust to an offset from UTC of zero hours-minutes-seeconds. System.out.println ( "zdt = " + zdt ); // Be aware: All three of these date-time objects represent the very same moment, the same point on the timeline. System.out.println ( "odt = " + odt ); System.out.println ( "instant = " + instant ); preparedStatement.setString ( 1 , "Our First Book" ); preparedStatement.setString ( 2 , odt.toString ( ) ); preparedStatement.executeUpdate ( ); } catch ( SQLException e ) { throw new RuntimeException ( e ); } } private void dropTable ( ) { String sql = """ DROP TABLE IF EXISTS book ; """; try ( Connection connection = this.dataSource.getConnection ( ) ; Statement statement = connection.createStatement ( ) ; ) { statement.executeUpdate ( sql ); } catch ( SQLException e ) { throw new RuntimeException ( e ); } } private void createTable ( ) { String sql = """ CREATE TABLE book ( id BIGINT AUTO_INCREMENT PRIMARY KEY , title VARCHAR(255) NOT NULL , created_on TIMESTAMP(6) NOT NULL ) ; """; try ( Connection connection = this.dataSource.getConnection ( ) ; Statement statement = connection.createStatement ( ) ; ) { statement.executeUpdate ( sql ); } catch ( SQLException e ) { throw new RuntimeException ( e ); } } // Constructor public App ( ) { this.dataSource = this.configureDataSource ( ); } private DataSource configureDataSource ( ) { com.mysql.cj.jdbc.MysqlDataSource dataSource = new com.mysql.cj.jdbc.MysqlDataSource ( ); dataSource.setDatabaseName ( "bogus_" ); dataSource.setServerName ( "localhost" ); dataSource.setPort ( 8090 ); dataSource.setUser ( "root" ); dataSource.setPassword ( "" ); // WARNING: Risky business, leaving your server unprotected, without security. return dataSource; } public static void main ( String[] args ) { App app = new App ( ); app.demo ( ); } private void dumpTime ( ) { String sql = "SELECT CURRENT_TIMESTAMP ;"; try ( Connection connection = this.dataSource.getConnection ( ) ; Statement statement = connection.createStatement ( ) ; ResultSet resultSet = statement.executeQuery ( sql ) ; ) { while ( resultSet.next ( ) ) { String now = resultSet.getString ( 1 ); System.out.println ( now + "\n" ); } } catch ( SQLException e ) { throw new RuntimeException ( e ); } } }
运行时:
zdt = 2023-08-14T14:26:20.708102-06:00[America/Edmonton] odt = 2023-08-14T14:26:20.708102-06:00 instant = 2023-08-14T20:26:20.708102Z BookRecord[id=1, title=Our First Book, odt=2023-08-14T20:26:20.708102-07:00] Aug 14, 2023 1:26:20 PM org.hibernate.Version logVersion INFO: HHH000412: Hibernate ORM core version 6.2.7.Final Aug 14, 2023 1:26:20 PM org.hibernate.cfg.Environment <clinit> INFO: HHH000406: Using bytecode reflection optimizer Aug 14, 2023 1:26:21 PM org.hibernate.bytecode.internal.BytecodeProviderInitiator buildBytecodeProvider INFO: HHH000021: Bytecode provider name : bytebuddy Aug 14, 2023 1:26:21 PM org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService INFO: HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] Retrieved via Hibernate… book = Book{id=1, title='Our First Book', createdOn=2023-08-14T20:26:20.708102Z}
4条答案
按热度按时间n53p2ov01#
如果数据源可以通过JNDI获得,那么您只需要设置配置的hibernate.connection. configuration属性- mtpettyp的答案说明了这一点。
如果您所处的环境中的数据源不是来自JNDI,请提供您自己的ConnectionProvider实现,并在构建会话工厂之前将其传递给Settings对象,或者在hibernate.connection.provider_class属性中指定其类名。如果您为Settings提供了一个示例,那么您可能可以示例化标准DatasourceConnectionProvider并给予您的DataSource。
frebpwbc2#
在您的hibernate.cfg.xml中:
xurqigkl3#
如果您使用Spring初始化和Spring会话工厂Bean,则可以像这样简单地传入数据源
其中dataSource引用在别处定义。
4uqofj5v4#
我找不到一个完整的例子来说明如何使用现有的
DataSource
示例仅通过代码(没有XML文件,没有JNDI)配置Hibernate/Jakarta Persistence。所以我把这个贴在这里。希望它能帮助其他人。下面是一个使用Java SE的示例,没有任何Jakarta EE应用服务器。
我用的是:
👉🏼 我用下面的代码严格配置了Hibernate。我没有写任何配置XML文件。
DataSource
代码javax.sql.DataSource
与Java SE捆绑在一起。我们需要一个接口的实现。在本例中,我们使用com.mysql.cj.jdbc.MysqlDataSource
类中JDBC驱动程序 MySQL Connector/J 提供的实现。我们在下面的方法中设置了
DataSource
实现的一个示例。有关详细信息,请参阅 Connector/J 手册的Configuration Properties。
休眠代码
有了这个
DataSource
示例,我们可以使用Hibernate连接到数据库服务器,执行查询,并将检索到的数据打包为对象。Book = Book{id=1,title ='我们的第一本书',createdOn=2023-08- 14 T20:26:20.708102Z}
完整示例代码
Book
类我们期望Hibernate示例化这个类的对象。以及我们完整的示例应用程序代码。代码:
1.重新创建一个表
book
。然后用单行重新填充该表。这两个步骤都直接使用JDBC,而不是Hibernate。1.使用Hibernate查询单行,并使用检索到的数据示例化
Book
对象。运行时: