最近开始学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