-
对实体 "XXX" 的引用必须以 ';' 分隔符结尾(需要对分号进行编码)
<property name="connection.url">jdbc:mysql://localhost:3306/test2?useUnicode=true;characterEncoding=gbk</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=gbk</property>
- F3之后,跳到了"需要附加jar或者zip文件"的黑白页面去了,需要做的就是将从官网上面下载的zip文件"attache"即可;记得当年MINA也有同样问题,处理方式也一样,其实查看解压文件,其实文件结构是基本一样的:
- 在开始使用配置文件配置Hibernate的映射关系,后来改为声明式的;但是运行时发现了"org.hibernate.MappingException: Unknown entity XXX",后来确定是因为在cfg.xml中mapping节点需要做调整:
<mapping resource="com/historycreator/hibernate/Event.hbm.xml" />修改为
<mapping class="com.historycreator.hibernate.Event"/> - Hibernate的查询有两种方式,一种通过指定Id的方式直接获得(session.byId(Test.class).load(16), byId的参数是声明类,load的参数是Id值);还有一种方式是通过SQL方式,SQL方式又分为两种:一种是通过HSQL的方式
Query query = session.createQuery("from Test where t1=:t1");
query.setParameter("t1", 16);
Test entity = (Test)query.uniqueResult();
需要注意的是:HQL的方式from后面跟着的是实体的名称(推测Hibernate将会根据实体声明的信息找到对应的映射表名形成最终的SQL文);HQL中的t1=:t1是指定t1字段参数名为"t1",参数值是通过"query.setParameter来进行指定;
第二种方式是使用原生的SQL:
SQLQuery sqlQuery = session.createSQLQuery("select * from test1 where t1=:t1")
sqlQuery.setParameter("t1", 16);
sq1Query.addEntity(Test1.class);
Test entity2 = (Test)sqlQuery.uniqueResult();
使用原生的SQL,创建的方法不同(createSQLQuery方法),而且还需要添加一步:sqlQuery.addEntity,来告诉session来如何将返回值进行类型转换; - 如果是需要对返回的Query/SQLQuery对象进行操作,需要使用list()方法获得元素列表:
for(Object item: sqlQuery.list()){
Test t = (Test)item; ...
} - 下午使用Hibernate进行构建SFS的数据库操作,但是发现了一个异常"Unknown table 'system_sequences' in information_schema",说是数据库方言错误;后来把*.cfg.xml里面的"dialect"Property注释掉,问题解决;所谓方言其实就是你的数据库种类以及具体类型,比如当时我是用的是Mysql里面的InnoDB模式,于是方言应该设置为:org.hibernate.dialect.MySQLInnoDBDialect(之前设置为H2Dialect);
- 在Hibernate里面配置表级别(数据库连接级别在*.cfg.xml中进行配置)映射有两种方式,一种是*.hbm.xml定义方式,还有一种就是声明的方式;这两种方式采用实在*.cfg.xml中的mapping节点中声明的,但是注意,如果是xml文件配置方式,mapping节点使用的属性是resource,但是声明方式属性使用的是class:
<mapping resource="com/alibaba/conf/event.xml"/>
<mapping class="com.alibaba.entity.event"/>
还有一种貌似更加牛逼的方式就是声明一个包体名称,下面的类无条件的将会被认为是采用声明/配置方式:<mapping package="com.alibaba.entity"/>,但是经过验证毛用没有,非常简单,hibernate本身并没有探测功能(比如你新添加了一个类,自动探测到),如果想要自动探测,只能是和Spring结合在一起了; - akka组件貌似很牛逼的样子 http://akka.io/ ;
- Hibernate拥有"正向工程"的功能,cfg.xml中hbm2ddl的Property,如果设置为create,那么当检测到不同,将会删掉表(schema),重新创建;validate,将会在运行时报错(在初始化sessionFactory的节点上面);update则是更新表结构(如果数据库字段比Entity多,将什么也不做,这样处理可能是因为数据库字段多不会报错,大不了值为空,但是如果Entity字段多,声明的字段值将没有地方保存);如果你不想使用此功能,就注释掉这个节点;正向工程其实和Entity Framework的Code-First很像;
- 读代码的时候看到动物快跑Hibernate的session事务处理机制是通过getTransaction()获得Transaction信息,然后try...catch中对trans对象进行rollback()操作,在finally中调用HibernateUtil的closeSession();这样处理感觉会更加完整;
- HibernateUtil中的创建session是放置在localThread上面的,为什么要这么做呢?closeSession的时候,读取的也是从当前线程读取;难道说如果HibernateUtil是设计被多线程访问(屁话,伦家都是static好不好),通过这种方式保证session在各个线程间是独立的;看到了一个死贴上面讲述都是:如果不适用localThread,土的掉渣的方式就是创建一个HashMap,以当前线程做Key,value放置响应对象;另外如果想要在一个LocalThread里面放置多个东东,可以向里面放置一个Hashtable/Map即可;
- 今天上午尝试使用多线程进行测试Hibernate的Util类的时候,发现了对于取最大+1获得主键值的方式还是有很大并发问题,获得了一样的主键值,插入的时候报错了;看来还是应该扔给系统来做这个自增长,自己来维护就不可以简单地取最大+1,而是要提供一个static的资源库,对于一个加锁变量进行+1取最大;
- 刚才尝试了一下使用AtomicInteger来进行控制,static块中从数据库中读取最大值,之后查处都是通过这个原子整型的incrementAndGet()方法进行获取+1值,完美的避免的并发问题;