1. 程式人生 > >【學習筆記】Hibernate連線oracle資料庫

【學習筆記】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  (?, ?, ?, ?) 這是插入語句,最後資料庫也成功插入了一條資料

在測試的過程中遇到了一個異常ServiceException,經查詢發現是配置資料庫url的時候把localhost寫成了location,導致資料庫連線不上。

附上異常資訊:

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