hibernate笔记

1.Field'userid' doesn't have a default value Exception in thread "main"org.hibernate.exception.GenericJDBCException: could not insert:[test.Users]

这是因为在对应的users.hbm.xml文件中userid的配置是 这个属性表示该属性由数据库自动生成,但是如果你没有设置默认值的话,数据库不知道怎么生成,所以就报错了

2.Could not parseconfiguration: /hibernate.cfg.xml
有两种可能,第一种xml中的语法错了,可以用ie浏览器打开查错;第二种是引用了错误的dtd文件,正确的是:http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd

3.inverse:是否将对集合对象的修改反映到数据库中,默认值为false,inverse=false的为主动方,由主动方负责维护关联关系。
 many-to-many关联关系中,一端设置inverse=”false”,另一端设置为inverse=”true”。在one-to-many关联关系中,设置inverse=”true”,由多端来维护关系表

4.hibernate事务提交的时候出现了这种错误:
org.hibernate.exception.LockAcquisitionException:Could not execute JDBC batch update
......
Caused by:java.sql.BatchUpdateException: Deadlock found when trying to getlock; try restarting transaction

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后跟实体类名(注意大小写)

 2).hbm文件是否导入(数据库对应表产生的话可以排除) 

 3).在对应hbm文件中是否使用了auto-import=false,如果用了就会导致mapping错误(本人遇到了,查了半天,切记!!!) 


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&amp;zeroDateTimeBehavior=convertToNull&amp;transformedBitIsBoolean=true  

这样就可以了

注意xml中&要写成&amp;


8.problem:复合主键的一对一映射(主键关联)要怎么弄??

9.正确的更新语句:

 update wlw.productin set propertyunit=?,note=? where storageinId=? and productId=?


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,

 3 表示hiberante无法将这种数据类型映射到你的java类中)

出现这个问题的原因是 通过Hibernate createSQLQuery() 方法进行查询,对应表中的列有 text类型的,方言导致的。

解决方法:自已建一个方言,继承于MySQLDialect ,引入registerHibernateType(Types.LONGVARCHAR,Hibernate.TEXT.getName());


然后将hibernate注册的方言改成自己的。如:
<prop key="hibernate.dialect">
util.MyMySQLDialect
</prop> 

package util;

import java.sql.Types;

import org.hibernate.Hibernate;
import org.hibernate.dialect.MySQLDialect;

public class MyMySQLDialect extends MySQLDialect{
public MyMySQLDialect(){   
        super();               
        registerHibernateType(Types.LONGVARCHAR,Hibernate.TEXT.getName());  
     
}

此外,在hibernate里面用SQLQuery查询的时候查出来的CHAR(n)类型只能取出第一个字符,也可以用这个方法解决:在里面加上一句
registerHibernateType(Types.CHAR,Hibernate.STRING.getName()); 
此外还有其他的一些
  registerHibernateType(Types.NVARCHAR,Hibernate.STRING.getName());
  registerHibernateType(Types.LONGNVARCHAR,Hibernate.STRING.getName());
    registerHibernateType(Types.DECIMAL,Hibernate.BIG_INTEGER.getName());

14.我把一个表a的一个非主键rfid设置成了not nullunique,然后另一个表b的主键做外键关联到rfid,当我用
b.getA().getId的时候得到的是rfid而不是a本身的主键,这是什么机制呢?

15.一些查询实例

HQL实例:

1. 查询表中的所有记录:from Category

2. 带有where子句的条件查询:from Category where c.name 'c5'

3. 结果根据某一字段排序:from Category order by c.name desc(desc表示降序排列,asc表示升序排列)

4. 去除重复记录获得单一记录:select distinct from Category order by c.name desc

5. 带有参数的查询:from Category where c.id :min and c.id :max。hql语句中’:min’ 表示的是参数,可以像jdbc中一样,为参数赋值。在hql中可以这样,这里也运用了链式编程:

session.createQuery("from Category where c.id :min and c.id :max")

.setInteger("min", 2)

.setInteger("max", 8);

6. 带参数hql查询的另外一种查询:from Category where c.id and c.id ?

7. hibernate分页查询 

Query session.createQuery("from Category order by c.name desc");

q.setMaxResults(3);

q.setFirstResult(0);

其中setMaxResult()是设置每页的最大显示量,setFirstResult()是设置其实元素从哪里开始,这里0代表最后一条元素。

8. 多表连接查询:select t.title, c.name from Topic join t.category c

9. HQL函数:

a) Count():select count(*) from Msg m

b) Max()-min()-avg():select max(m.id), min(m.id), avg(m.id), sum(m.id) from Msg m

c) Between:from Msg where m.id between and 5

d) In:from Msg where m.id in (3, 4, 5)

10. Is null;is not null:from Msg where m.cont is not null

11. Is empty:from Topic where t.msgs is empty

12. Like:from Topic where t.title like '%5'。'%'匹配所有字符,'_'匹配单个字符。

13. 

一些功能函数,但是不重要了解即可:select lower(t.title)," +

  "upper(t.title)," +

  "trim(t.title)," +

 "concat(t.title, '***')," +

  "length(t.title)" +

     from Topic ")

Trim()是去掉首尾空格,返回字符串的副本,concat()将字符串欲查询出的字符串连接。

14. Abs()-sqrt()-mod():select abs(t.id)," "sqrt(t.id)," "mod(t.id,2)" from Topic 

15. 获取当前的时间:select current_date, current_time, current_timestamp, t.id from Topic t

16. Having子句:select t.title, count(*) from Topic group by t.title having count(*) <= 1

17. Existfrom Topic where not exists (select m.id from Msg where m.topic.id=t.id)

需要注意的一点:in同样可以实现exist的功能,但是exist的执行效率较高。

18. Update的用法:update Topic set t.title upper(t.title)

16.hql看用聚集函数sum返回的是Long类型的值,可用Long.intValue转成int值


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值