【學習筆記】Hibernate連線oracle資料庫
一、 Hibernate介紹
Hibernate是基於物件/關係對映(ORM,Object/Relational Mapping)的一個解決方案。ORM方案的思想是將物件模型表示的物件對映到關係型資料庫中,或者反之。Hibernate目前是ORM思想在Java中最成功、最強大的實現。它於2001年的年末釋出第一個版本,立即引起了廣泛的注意。2003年6月,Hibernate2發表,並且獲得Jolt大獎,進而被JBoss吸納成為它的一個子專案。2005年3月,Hibernate 3發表,其中做了一些比較重大的改進。本文以Hibernate5為基礎編寫。
另外,Hibernate除了可以在J2EE容器中執行外,還可以執行在Java應用程式中。本文就是以Java應用程式為例來介紹它。
二、配置開發環境
本文以一個Java應用程式(Java Application)為例,介紹如何使用Hibernate來進行資料庫操作。
在進行Hibernate開發之前,需要首先獲得Hibernate類庫、相應資料庫的JDBC驅動類庫。Hibernate類庫可以從http://www.hibernate.org中下載。我用的Hibernate版本是5.3.2。而JDBC驅動可以根據不同的資料庫來選擇,在這個例子中,使用的是Oracle資料庫,那麼相應的JDBC驅動可以從Oracle安裝目錄\ora92\jdbc下獲得。其他的資料庫請根據相關的說明獲得。
下載Hibernate包後,可以將它解壓到一個資料夾,此處假設為C:\hibernate-release-5.3.2.Final,然後將C:\hibernate-release-5.3.2.Final\lib\required下的jar包複製到專案的lib資料夾下。(一般只需要dom4j、cglig、commons-logging、commons-collections、log4j、ehcache、asm、jta、antlr這些類庫就可以了)
還需要一個Oracle驅動jar包。
做完這些配置後,就可以在此基礎上進行基於Hibernate的Java程式開發了。
三、開發基於Hibernate的應用
這裡我用的是Oracle自帶的Emp表測試。
1.首先配置一個hibernate.cfg.xml來指定Hibernate所使用的資料庫以及使用者名稱、密碼等其他相關的配置,我們在此使用xml檔案,它的內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置資料庫的基本資訊 -->
<!--資料庫連線url-->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:gy</property>
<!--連線資料庫的Driver-->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<!--使用者名稱-->
<property name="connection.username">scott</property>
<!--密碼-->
<property name="connection.password">admin</property>
<!-- 配置hibernate指定資料庫的方言 -->
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<!-- 配置hibernate的基本資訊 -->
<!-- 列印sql語句到控制檯 -->
<property name="show_sql">true</property>
<!-- 格式化sql語句 -->
<property name="format_sql">true</property>
<!-- 指定自動生成資料表的策略 -->
<property name="hbm2ddl.auto">update</property>
<!-- 配置對映檔案 -->
<mapping resource="com/guyun/test/emp.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.封裝一個Emp實體類
import java.util.Date;
/**
* 員工實體類
*/
public class Emp {
private int empno;
private String ename;
private String job;
private Date hiredate;
public Emp() {
super();
}
//這裡的構造器沒有empno
public Emp(String ename, String job, Date hiredate) {
super();
this.ename = ename;
this.job = job;
this.hiredate = hiredate;
}
public int getEmpno() {
return empno;
}
public void setEmpno(int empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", hiredate=" + hiredate + "]";
}
}
3.配置emp.hbm.xml對映檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- name對應實體類 ,table對應資料庫表名 -->
<class name="com.guyun.entity.Emp" table="emp">
<!-- 主鍵 -->
<id name="empno" column="empno" type="int">
<!-- 採用演算法為主鍵自動設定值,配置之後就不用為主鍵設定值(配置這個之後自已設定的主鍵值將不採用) -->
<generator class="increment"></generator>
</id>
<!-- name對應Emp.java裡欄位名稱,column對應資料庫的列名 ,type對應欄位型別 -->
<property name="ename" column="ename" type="java.lang.String"></property>
<property name="job" column="job" type="java.lang.String"></property>
<property name="hiredate" column="hiredate" type="java.sql.Date"></property>
</class>
</hibernate-mapping>
4.最後編寫測試類
import java.sql.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import com.guyun.entity.Emp;
public class EmpTest {
public static void main(String[] args) {
//建立一個sessionFactory物件
SessionFactory factory = new Configuration().configure().buildSessionFactory();
//建立一個session
Session session = factory.openSession();
//開啟事務
Transaction transaction = session.beginTransaction();
//執行插入資料庫
Emp emp = new Emp("孤雲","Boss",new Date(0));//這裡不設定主鍵是因為在對映檔案中配置了自動設定主鍵
session.save(emp);
//提交事務
transaction.commit();
//關閉session
session.close();
//關閉sessionFactory
factory.close();
}
}
最後是控制檯輸出的結果
Hibernate: select max(empno) from emp 這是生成的主鍵
Hibernate: insert into emp (ename, job, hiredate, empno) values (?, ?, ?, ?) 這是插入語句,最後資料庫也成功插入了一條資料
附上異常資訊:
ERROR: The Network Adapter could not establish the connection
Exception in thread "main" org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:179)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:84)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:474)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at com.guyun.test.EmpTest.main(EmpTest.java:15)
Caused by: org.hibernate.exception.GenericJDBCException: Error calling Driver#connect
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:118)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41)
at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.addConnections(DriverManagerConnectionProviderImpl.java:363)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.<init>(DriverManagerConnectionProviderImpl.java:282)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.<init>(DriverManagerConnectionProviderImpl.java:260)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections$Builder.build(DriverManagerConnectionProviderImpl.java:401)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:112)
at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:75)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:100)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 14 more
Caused by: java.sql.SQLException: The Network Adapter could not establish the connection
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:412)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38)
... 29 more
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:359)
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:422)
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:672)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:237)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1042)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301)
... 34 more
Caused by: java.net.UnknownHostException: location
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
at java.net.InetAddress.getAllByName(InetAddress.java:1192)
at java.net.InetAddress.getAllByName(InetAddress.java:1126)
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:114)
at oracle.net.nt.ConnOption.connect(ConnOption.java:123)
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:337)
... 39 more
最後附上Hibernate和Oracle驅動包的下載連線:連結:https://pan.baidu.com/s/1ZC9b2r4xZGIwK_L6DYmM0A 密碼:z8l6