- 众所周知,hibernate是优秀的ORM框架,不过在使用过程中,还是遇到了不少令人费解的问题。
- hibernate有两个配置文件,一个是hibernate.cfg.xml,另外一个是hibernate.properties。前者是当面5.2版本推荐的,而后者是曾经用过的版本,可能为了兼容,这两个配置文件都可以使用,并且先从后者读取参数。至于前者会不会覆盖,有待深究。我一般只用前者,后者都不会放在项目中,当然会提示找不到该文件,不过无碍。
- 有意思的是,springBoot放弃了xml,转向property,并且通过层次的变量名代替原先xml复杂的结构,而hibernate正好相反;
- 既然所有配置都可以放在hibernate.cfg.xml,不幸的是,我没能从hibernate官方网页上找到所有配置集成的页面。
- 当我把hibernate从4X升级到5X时,提示MySQL5InnoDBDialect被弃用
package org.hibernate.dialect;
/** A Dialect for MySQL 5 using InnoDB engine
*
* @author Gavin King,
* @author Scott Marlow
* @deprecated Use "hibernate.dialect.storage_engine=innodb"
environment variable or JVM system property instead.
*/
@Deprecated
public class MySQL5InnoDBDialect extends MySQL5Dialect {
@Override
protected MySQLStorageEngine getDefaultMySQLStorageEngine() {
return InnoDBStorageEngine.INSTANCE;
}
}
尽管说提示说的很明确,需要在系统的环境变量或者java虚拟机配置hibernate.dialect.storage_engine=innodb,但下意识的还是觉得上面的变量是配置在hibernate.cfg.xml中,于是自动建表时,使用的引擎还是MyISAM
而使用百度搜索MySQL5Dialect,出现的内容重复的东西太多。无奈在Stack Overflow上提问,得到正确答案。
https://stackoverflow.com/questions/48062256/where-to-put-hibernate-dialect-storage-engine-property不得不说,MySQL5Dialect和MySQL55Dialect,这种命名只差一个5,很恼人,尤其是在没有系统浏览hibernate类目录结构时,很容易疏忽。Stack Overflow上类似的问题不少,但回答很少且不是正确答案,我提问的有正确的回答还是挺幸运。
除了查阅参数不便之外,hibernate异常以及日志记录也比较佛性,例如show_sql,即便打印了sql,并不是真正的执行sql,替换的变量没有填充进去,这一点也很烦躁。如果出错,你拷贝出来的sql并不是最终执行的sql,需要自己替换,提高了调试排错的难度。
当然,我在替换MySQL5InnoDBDialect时,直接用它的父类去替换是有问题的,控制变量作为基本的实验方法,应当遵守。但Hibernate既然提供了MySQL55Dialect这样的类,应当在被弃用的方法中说明,毕竟配置环境变量或设置JVM变量这样的替代方法,相对来说比较复杂,对版本升级并不友好。
顺带一枪,聊一聊mybatis,面试的时候,我经常问一些工作了三五年的老司机,mybatis的优势,比较普遍的回答是把sql写在xml文件中,容易看清业务逻辑,以及适合复杂的sql。问题是,真是这样子嘛?
- mybatis对于sql拼接参数,相对来说比较繁琐,而在阅读业务代码时,如果需要通过sql来理解业务逻辑,代码是有多搓。一般来说,稍微复杂的sql,应当在方法中加上清晰的注释,去理解大长串的sql,实在是下下策。
另外我们在阅读代码时,习惯一个一个放大点进去,从java代码跳到xml,不累嘛?
回头看看springBoot,springBoot在使用时,集成了hibernate,同时也提供了自己的jdbcTemplete,并且一些简单的查询可以通过方法名直接出结果。可以说springBoot也意识到了hibernate的一些不足,所以提供了一些额外的使用方法,但并没有完全抛弃hibernate,尤其是对象-sql结果这样的映射,完全吸纳了hibernate,这确实是hibernate的精髓。