ANSI SQL-99标准定义了下列隔离级别:
Hibernate 在配置文件中声明事务的隔离级别,Hibenate获取数据库连接后,将根据隔离级别自动设置数据库连接为指定的事务隔离级别。
<propertyname="connection.isolation">8</property>
● 未提交读(ReadUncommitted):隔离事务的最低级别,只能保证不会读取到物理上损坏的数据。Hibernate配置:1;允许产生:1,2,3
● 已提交读(ReadCommitted):常见数据库引擎的默认级别,保证一个事务不会读取到另一个事务已修改但未提交的数据。Hibernate配置:2;允许产生:1,2
● 可重复读(RepeatableRead):保证一个事务不能更新已经由另一个事务读取但是未提交的数据。相当于应用中的已提交读和乐观并发控制。Hibernate配置:4;允许产生:1
●可串行化(Serializable):隔离事务的最高级别,事务之间完全隔离。系统开销最大。Hibernate配置:8;这种情况很容易造成死锁的问题,hibernate表现为:Deadlockfound when trying to get lock; try restartingtransaction
所以在hibernate的配置文件中加入上面那一句配置文件,把级别改成2就行了。
参考自:http://www.blogjava.net/freeman1984/archive/2009/08/31/293868.html
5.hibernate做删除等操作的时候,记得都要用事务,否则的话操作无效!
6.org.hibernate.hql.ast.QuerySyntaxException:User is not mapped [from User].
错误原因:1).from后跟实体类名(注意大小写)
7.Cannot convert value '0000-00-00 00:00:00'from column 1 to TIMESTAMP
原因:在mysql数据库中,如果Date类型的字段为空或者值为'0000-00-00"时,用Hibernate的生成类时就会报错解决方法: 把jdbc.url变为:
jdbc.url=jdbc:mysql://192.168.3.7:3306/mmcms_pmi?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
这样就可以了
注意xml中&要写成&
8.problem:复合主键的一对一映射(主键关联)要怎么弄??
9.正确的更新语句:
10.从工厂里取出一个session以后一定要记得关掉,即
finally{if(session!=null)session.close();}
否则的话有时候取一个session会取到以前的session,从而导致从这个session查到的数据有可能是未更新的
11.hibernate缓存
一级缓存
(1)session的缓存只在session未关闭前有效,关闭后再查同的数据会重新连库
(2)我们可以手工清除session中的缓存:evict和clear
(3)如果我们清掉session中的缓存,或是第一次查询这个数据,都会引起连库
(4)save,update,savaOrUpdate,load,get,list,iterate,lock等方法都会将对象放在一级缓存中,具体可以在上例的基础上进行测试。
(5)session一级缓存不能控制缓存数量,所以在大批量操作数据时可能造成内存溢出,这时我们可以用evict,clear来清除缓存中的内容
(6)session在web开发应用中,一般只在一个用户请求时进行缓存,随后将会关闭,这个session的存活时间很短,所以它的作用不大,因此提出了二级缓存在概念。
二级缓存:
二级缓存通常是第三方来实现,而我们使用时只需要对它进行配置即可。下面演示使用二级缓存的具体步骤。
>>步骤一,在主配置文件中指明支持使用二级缓存:
<propertyname="hibernate.cache.use_second_level_cache">true</property>
我们也可以不配置此属性,因为默认就是打开二级缓存。
>>步骤二、配置第三方缓存机制:
<propertyname="hibernate.cache.provider_class">
org.hibernate.cache.OSCacheProvider
</property>由于我们这里选择了OSCacheProvider(它貌似也是hibernate官方开发得缓存机制)来提供缓存,所以还需要把它的缓存配置文件放在src目录下以使配置能被读到,这里即是把hibernate解压下的etc目录中的oscache.properties文件复制到src目录下。
>>步骤三、两种方式指定要缓存的实体类,一种是在主配置文件中配置(注意class是完整的类名):<class-cacheclass="com.asm.hibernate.domain.User"usage="read-only"/>
另一种是在实体配置文件(映射文件)配置:比如在User.hbm.xml 的class元素下配置如下内容:<cacheusage="read-only"/>关于usage属性值的说明:
read-only:如果你的应用程序只需读取一个持久化类的实例,而无需对其修改,那么就可以对其进行只读
缓存。这是最简单,也是实用性最好的方法。
read-write:如果应用程序需要更新数据,那么使用“读/写缓存”
比较合适。如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolationlevel),那么就决不能使用这种缓存策略。
nonstrict-read-write:如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存
策略。
transactional:Hibernate的事务缓存策略提供了全事务的缓存支持,例如对JBossTreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定为其hibernate.transaction.manager_lookup_class属性。
12.hql不支持union。。。。
13.org.hibernate.MappingException: No Dialect mapping for JDBCtype:-1
(这里-1表示hibernate根本就不认识这种数据类型,也有可能是3,
出现这个问题的原因是 通过Hibernate createSQLQuery() 方法进行查询,对应表中的列有 text类型的,方言导致的。
解决方法:自已建一个方言,继承于MySQLDialect ,引入registerHibernateType(Types.LONGVARCHAR,Hibernate.TEXT.getName());
然后将hibernate注册的方言改成自己的。如:
<prop key="hibernate.dialect">
util.MyMySQLDialect
</prop>
此外,在hibernate里面用SQLQuery查询的时候查出来的CHAR(n)类型只能取出第一个字符,也可以用这个方法解决:在里面加上一句
HQL实例:
1.
2.
3.
4.
5.
session.createQuery("from
.setInteger("min",
.setInteger("max",
6.
7.
Query
q.setMaxResults(3);
q.setFirstResult(0);
其中setMaxResult()是设置每页的最大显示量,setFirstResult()是设置其实元素从哪里开始,这里0代表最后一条元素。
8.
9.
a)
b)
c)
d)
10.
11.
12.
13.
一些功能函数,但是不重要了解即可:select
Trim()是去掉首尾空格,返回字符串的副本,concat()将字符串欲查询出的字符串连接。
14.
15.
16.
17.
需要注意的一点:in同样可以实现exist的功能,但是exist的执行效率较高。
18.
16.hql看用聚集函数sum返回的是Long类型的值,可用Long.intValue转成int值