请先关注 [低调大师] 公众号 优秀的自媒体个人博客,低调大师,许军

低调大师

您现在的位置是:首页>文章详情

文章详情

为什么很多人不愿意用hibernate了?

2020-01-13 98热度

最近想温习一遍JAVA框架,理所当然的从最基本的SSH开始整合,然而亲身体会了一下hibernate的可怕之处。

一、hibernate优势

hibernate让你不用写sql了,这不单可以让你的应用更好移植其它数据库,更主要的是让程序员更专注业务逻辑、数据关系、对象关系等。hibernate对一对多,多对多关系实现是非常好的。很关键一点,它支持lazy,可以让你的数据只在需要的时候被加载,听起来很完美。hibernate还有一个更牛的就是HQL,这是完全可以把查询映射到你OO模型的查询语言,和mybatis的映射比起来,还是更方便和更强大的。

1、@Lazy注解是什么?

@Lazy注解用于标识bean是否需要延迟加载,源码如下:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Lazy { /** * Whether lazy initialization should occur. */ boolean value() default true; }

只有一个参数,默认是true,也就是说只要加了这个注解就会延迟加载。

2、@Lazy注解怎么使用

没加注解之前主要容器启动就会实例化bean,如下:

AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class); 

创建user实例

而加上@Lazy注解则必须在第一次调用的时候才会加载如下:

@Scope @Lazy @Bean(value="user0",name="user0",initMethod="initUser",destroyMethod="destroyUser") public User getUser(){ System.out.println("创建user实例"); return new User("张三",26); }
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class); User bean2 = applicationContext2.getBean(User.class);
创建user实例 实例1 === User [userName=张三, age=26]

@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间

二、hibernate致命缺陷

看完优势之后,感觉hibernate无所不能了,无敌是多么的寂寞。但其实恰恰相反,强烈建议不用hibernate,尤其是需要处理大量数据或者大并发情况的网络服务,那么现在开始说说hibernate的问题。

1、难以使用数据库的一些功能

hibernate将数据库与开发者隔离了,开发者不需要关注数据库是Oracle还是MySQL,hibernate来帮你生成查询的sql语句,但问题来了,如果你想用某种数据库特有的功能,或者要让查询的sql完全符合你的心意,这就难了。如果使用hibernate,虽然它能对生成的查询进行一定程序的定制,但就有点隔靴挠痒的感觉了,而且你开发起来付出的代价更大。至于hibernate对native sql的支持,还是挺完善的,这种native sql还能返回non-managed entity,不走hibernate的cache,优化是搞定了,但如果整个项目都这么整,那还是用mybatis吧。

很多时候,我们都有一个需求:得到数据库服务器的当前时间。这是因为本机时间和服务器时间是有差别的。各种数据库都提供了函数来获得,比如,mysql,可以用“select now()”。hibernate也提供了一个函数current_timestamp(说起timestamp,个人认为数据库的timestamp做的很差,它居然和datetime是一个数量级的(精确度),这怎么可以用来表示真正的stamp啊!)。可是,你却无法用直接使用“select current_timestamp()”来获得服务器的当前时间,你还必须加上一个查询的表!比如,“select current_timestamp() from tbl_Good”。个人十分郁闷,我只是想用这个简单功能而已,为什么我一定要知道数据库里面的表格呢????更何况还必须建立映射。。。。。。

不是我不明白,这世界太复杂了 。每样产品都是拼命的复杂化,其实,它们实在是忽略了一般的用户只需要一小部分功能而已。默认的功能应该是能够满足普通用户的常见需求的,那样才算是一个好的产品。我不认为hibernate做到了这点。

2、满足不了程序对cache的需求

很多web服务,对cache的依赖是非常大的,hibernate自带的cache按理说也是很强大的,但还是满足不了很多需求。

3、耦合度太高

hibernate的确是在你项目开发的时候节约了很多时间,但是它对你的业务逻辑模型和数据库模型互相依赖的程序太高了。短期没啥问题,但随着项目的变迁,这些都会改变,在维持这种仅仅耦合的关系的时候,你会发信你的代码特别脆弱,随便改一处数据库的schema,整个java项目可能要改几十次。而且现在mybatis的自动mapping做的也很好,开发起来也没花多长时间,等项目进入中后期,你需要大量定制和优化查询的时候,mybatis的开发效率就更明显了。

4、debug太难

作为一个后端程序员,我比较喜欢每一行代码我都精确知道它到底在干什么。尤其是数据库访问的代码,往往系统的瓶颈就在这些地方产生,每一行都不能小看。我看过hibernate早期版本的部分代码,比我想象的复杂和强大很多。的确很多地方Hibernate可以强大的只用一行代码解决很多问题,但比如说一个update()或者save()到底做了什么,这里既有hibernate本身的逻辑,也有你应用的逻辑,如果这一行产生了问题,你该如何去做?我个人觉得这是很难搞的,还不如一开始费点事,用mybatis这种。

5、写入和查询语句不执行

写个简单的session.save(obj)语句,你却发现它并不执行。原来是因为数据库表是事务表,所以,需要把这个语句放到事务里面执行。这个还好说。

过不不久,你发现query查询居然没有执行!你把hibernate生成的sql放数据库里,居然还好用,它也不是老不出,一段时间之后,它就执行了,会给你一个结果。查询语句居然不是实时的...... 在google了很长时间之后(半天),才看到一个说法:把查询语句用事务封装起来。于是这么做了,发现hibernate能够马上执行查询语句了。

6、执行本地sql语句返回结果奇特

数据库中有几个表,,需要进行左连接访问,用sql很简单,但是。当你打算使用hql的时候,你会发现,配置那个麻烦啊,没有执行写sql来的简单,我在做SSH的项目练习,至今还没搞定左连接。所以,你想直接写sql语句,期待hibernate能够像普通JDBC那样执行,返回一个正确的结果,然并卵,hibernate返回的结果。。。

数据库表里面有一个字段类型char(4),里面的值都是“good”,可是,hibernate查询回来的居然只有一个字符:“g”。只好查看hibernate的ref里面的Native Sql那章了,看到有如下的例子:

sess.createSQLQuery("SELECT * FROM CATS") .addScalar("ID", Hibernate.LONG) .addScalar("NAME", Hibernate.STRING) .addScalar("BIRTHDATE", Hibernate.DATE)

你才知道,你需要使用addScalar方法来指定某个返回字段的类型!注意的是,方法里面的第一个参数是返回字段的名称。哦,你恍然大悟。立马这样修改了自己的代码,慢着,你突然发现居然只返回了你使用addScalar指定了类型的几个字段!原来,hibernate就是这样处理的,你要返回的每个字段都必须使用addScalar指定!

7、写入数据库字符串乱码

简单的数据库,简单的表格,简单的字段,是字符串类型,utf-8编码。用hibernate写入正常文本,写进去就变成乱码了。显然是编码不一致的问题。hibernate里面居然没有说明如何配置。好在网络上有人说可以在hibernate的配置文件里面加上一句配置:

<property name="connection.characterEncoding">UTF-8</property> 

这句配置并不是给hibernate用的,它会传递给底层的jdbc。告诉jdbc字符串是utf-8的编码。可能有的数据库会需要你再配置一个(以上配置mysql可以):

<property name="connection.useUnicode">true</property>

三、群众的眼光的雪亮的,千万不要逆天而行

 

 

相关博文

SSH、SSM及Springboot的概念、优点、缺点及区别

收藏 (0)

相关文章

    文章评论

    共有0条评论来说两句吧...