標籤:
最近開始學Hibernate,看的是李剛的那本《輕量級java ee公司專屬應用程式實戰》。頭一個hibernate程式,我原原本本的按照書上例子寫下來,同時只是改動了些mysql的串連參數,並且在mysql中建立了一個hibernate資料庫,僅此而已。然而預想不到的事情發生了……程式寫好之後,運行,報錯
Hibernate: insert into news_table (title, content) values (?, ?)
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not insert: [org.crazyit.app.domain.News]
…………此處省略
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table ‘hibernate.news_table‘ doesn‘t exist
…………此處省略
當時我就蛋疼了……情況是這樣的,如果在mysql中把news_table表建好,然後運行成功,這說明串連肯定是沒問題的。可就是不能自動建表,百度啊,遇到同樣問題的人不少,按照他們所說的一個個去解決,可是還是沒有效果。csdn上也發帖問了,有人說是: <propertyname="hibernate.hbm2ddl.auto">update(create)</property>這個設定有問題,應該用update。好吧,我敢說我本來用的就是update,還是會出錯。。有人說是什麼mysql引擎不配對的緣故,好吧,我敢說<property
name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>這樣設定,在mysql的設定檔ini中什麼引擎之類的也是innodb的(這個不太瞭解,隨便說點),當時我想問題肯定也不在這。還有人說,可能是你持久類的欄位設定成為關鍵字,這個更不靠譜了。。。。。
後來我想也許是版本相容問題,書上說的是用Hibernate3我用的是hibernate4。好吧我就重新下載hibernate3還是沒用。。。。。。就這樣,兩天下來,什麼各種方式都嘗試了,還是報一樣錯
最後實在沒法了,看了下hibernate的視頻教程,一步一步跟著做,每一個細節都不放過,嘗試著hibernate.cfg.xml和**.hbm.xml的每一個配置。。。。。終於才被我發現了
原來的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">liaobin1992</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="org/crazyit/app/domain/News.hbm.xml"/>
</session-factory>
</hibernate-configuration>
更改之後的配置:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
把這行換成:
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
這樣就行了 ,然後整個世界都安靜了。。
雖然沒明白為什麼這麼做,但是終於解決了問題,還是有點點的欣慰。。。
哪位大俠路過能幫忙解釋下 ,這是為什嗎?
原因如下:
本文講述Hibernate不同資料庫的串連及SQL方言。Hibernate不同資料庫的串連可能會出現錯誤,有一種情況是由於Hibernate SQL方言設定不正確而導致的。
如果出現如下錯誤,則可能是Hibernate SQL方言 (hibernate.dialect)設定不正確。
Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]‘last_insert_id‘ 不是可以識別的 函數名。
一、hibernate的dialect
| |
| RDBMS |
方言 |
| DB2 |
org.hibernate.dialect.DB2Dialect |
| DB2 AS/400 |
org.hibernate.dialect.DB2400Dialect |
| DB2 OS390 |
org.hibernate.dialect.DB2390Dialect |
| PostgreSQL |
org.hibernate.dialect.PostgreSQLDialect |
| MySQL |
org.hibernate.dialect.MySQLDialect |
| MySQL with InnoDB |
org.hibernate.dialect.MySQLInnoDBDialect |
| MySQL with MyISAM |
org.hibernate.dialect.MySQLMyISAMDialect |
| Oracle (any version) |
org.hibernate.dialect.OracleDialect |
| Oracle 9i/10g |
org.hibernate.dialect.Oracle9Dialect |
| Sybase |
org.hibernate.dialect.SybaseDialect |
| Sybase Anywhere |
org.hibernate.dialect.SybaseAnywhereDialect |
| Microsoft SQL Server |
org.hibernate.dialect.SQLServerDialect |
| SAP DB |
org.hibernate.dialect.SAPDBDialect |
| Informix |
org.hibernate.dialect.InformixDialect |
| HypersonicSQL |
org.hibernate.dialect.HSQLDialect |
| Ingres |
org.hibernate.dialect.IngresDialect |
| Progress |
org.hibernate.dialect.ProgressDialect |
| Mckoi SQL |
org.hibernate.dialect.MckoiDialect |
| Interbase |
org.hibernate.dialect.InterbaseDialect |
| Pointbase |
org.hibernate.dialect.PointbaseDialect |
| FrontBase |
org.hibernate.dialect.FrontbaseDialect |
| Firebird |
org.hibernate.dialect.FirebirdDialect
|
二、MySQL:InnoDB和MyISAM的差別
(註:MySQLInnoDBDialect與MySQLMyISAMDialect繼承自MySQLDialect。)
InnoDB和MyISAM是MySQL最重要的兩種資料存放區引擎,兩者都可用來儲存表和索引,各有優缺點,視具體應用而定。基本的差別為:MyISAM 類型不支援交易處理等進階處理,而InnoDB類型支援。MyISAM類型的表強調的是效能,其執行數度比InnoDB類型更快,但是不提供事務支援,而 InnoDB提供事務支援以及外部鍵等進階資料庫功能。
InnoDB 給 MySQL 提供了具有事務(commit)、復原(rollback)和崩潰修複能力(crash recovery capabilities)、多版本並發控制(multi-versioned concurrency control)的事務安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行級鎖(locking on row level),提供與 Oracle 類似的不加鎖讀取(non-locking
read in SELECTs)。InnoDB鎖定在行級並且也在SELECT語句提供一個Oracle風格一致的非鎖定讀。另外InnoDB是為處理巨大資料量時的最大效能設計。它的CPU效率可能是任何其它基於磁碟的關聯式資料庫引擎所不能匹敵的。MySQLInnoDBDialect基於上也就有InnoDB相同的功能.
InnoDB儲存引擎被完全與MySQL伺服器整合,InnoDB儲存引擎為在主記憶體中快取資料和索引而維持它自己的緩衝池。 InnoDB儲存它的表&索引在一個資料表空間中,資料表空間可以包含數個檔案(或原始磁碟分割)。這與MyISAM表不同,比如在MyISAM表中每個表被存在分離的檔案中。InnoDB 表可以是任何尺寸,即使在檔案尺寸被限制為2GB的作業系統上。
InnoDB是事務安全的.它與BDB類型具有相同的特性,它們還支援外鍵.InnoDB表格速度很快.具有比BDB還豐富的特性,因此如果需要一個事務安全的儲存引擎,建議使用它.如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表。
在 http://www.innodb.com/上可以找到 InnoDB 最新的資訊。InnoDB
手冊的最新版本總是被放置在那裡,並且在那裡可以得到 InnoDB 的商業許可(order commercial licenses)以及支援。
MyISAM是MySQL預設儲存引擎。每個MyISAM在磁碟上儲存成三個檔案。第一個檔案的名字以表的名字開始,副檔名指出檔案類型。.frm檔案儲存體表定義。資料檔案的副檔名為.MYD (MYData)。索引檔案的副檔名是.MYI (MYIndex)。
MyISAM基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序存取方法) 的縮寫,它是儲存記錄和檔案的標準方法.與其他儲存引擎比較,MyISAM具有檢查和修複表格的大多數工具. MyISAM表格可以被壓縮,而且它們支援全文檢索搜尋.它們不是事務安全的,而且也不支援外鍵。如果事物復原將造成不完全復原,不具有原子性。如果執行大量的SELECT,MyISAM是更好的選擇。
MyIASM是IASM表的新版本,有如下擴充:
·二進位層次的可移植性。
·NULL列索引。
·對變長行比ISAM表有更少的片段。
·支援大檔案。
·更好的索引壓縮。
·更好的鍵碼統計分布。
·更好和更快的auto_increment處理。
下面是已知的兩者之間的差別,僅供參考。
1.InnoDB不支援FULLTEXT類型的索引。
2.InnoDB 中不儲存表的具體行數,也就是說,執行select count(*) from table時,InnoDB要掃描一遍整個表來計算有多少行,但是MyISAM只要簡單的讀出儲存好的行數即可。注意的是,當count(*)語句包含 where條件時,兩種表的操作是一樣的。
3.對於AUTO_INCREMENT類型的欄位,InnoDB中必須包含只有該欄位的索引,但是在MyISAM表中,可以和其他欄位一起建立聯合索引。
4.DELETE FROM table時,InnoDB不會重建立立表,而是一行一行的刪除。
5.LOAD TABLE FROM MASTER操作對InnoDB是不起作用的,解決方案是首先把InnoDB表改成MyISAM表,匯入資料後再改成InnoDB表,但是對於使用的額外的InnoDB特性(例如外鍵)的表不適用。
另外,InnoDB表的行鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表,例如update table set num=1 where name like “%aaa%”。
任何一種表都不是萬能的,只用恰當的針對業務類型來選擇合適的表類型,才能最大的發揮MySQL的效能優勢。
附:MySQL的另兩種儲存引擎,MEMORY和MERGE
MEMORY儲存引擎使用存在記憶體中的內容來建立表。每個MEMORY表只實際對應一個磁碟檔案。MEMORY類型的表訪問非常得快,因為它的資料是放在記憶體中的,並且預設使用HASH索引。但是一旦服務關閉,表中的資料就會丟失掉。
MERGE儲存引擎是一組MyISAM表的組合,這些MyISAM表必須結構完全相同。MERGE表本身沒有資料,對MERGE類型的表進行查詢、更新、刪除的操作,就是對內部的MyISAM表進行的。
MEMORY類型的儲存引擎主要用於那些內容變化不頻繁的代碼錶,或者作為統計操作的中間結果表,便於高效地堆中間結果進行分析並得到最終的統計結果。對 MEMORY儲存引擎的表進行更新操作要謹慎,因為資料並沒有實際寫入到磁碟中,所以一定要對下次重新啟動服務後如何獲得這些修改後的資料有所考慮。
MERGE用於將一系列等同的MyISAM表以邏輯方式組合在一起,並作為一個對象引用它。MERGE表的優點在於可以突破對單個MyISAM表大小的限制,通過將不同的表分布在多個磁碟上,可以有效改善MERGE表的訪問效率。
原文出處:
http://blog.csdn.net/biangren/article/details/8010018
http://blog.csdn.net/moonsheep_liu/article/details/6416546
[轉]Hibernate不能自動建表解決辦法及Hibernate不同資料庫的串連及SQL方言