例如用户在系统中,保存的信息包括简要信息(用户名、联系电话、Email、性别)和一些图像信息(照片)。
 
     但是在系统设计时,我的设计方式都是遵循业务的需要,设计一个“用户”类,包含用户名、联系电话、Email、性别和照片信息。这个时候我是不会考虑数据库设计的,这是一个设计原则:“ 不因为实现妨碍设计 ”。
 
     在后面的数据库设计中因为照片比较大,所以保存的时候,会设计成两个表:用户简要信息表和用户照片表,两个表通过“用户ID”字段关联。
 
     如果使用JDBC实现比较简单,直接使用SQL,使用联合查询查到用户所有信息,返回成为对象,比较简单。但是因为项目早期的设计开发人员选择了Hibernate,只有沿着这个方向做了,我发现比较困难,因为Hibernate的机制就是一个表对应一个“实体对象”。
 
     没有办法,我只能建立两个实体对象,业务对象User中,改成这样:
 

class User{
UserSimpleInfo sinfo;
UserPhotoIfo pinfo;
}
 
     感觉真够滑稽的。也许还有好的解决方案,只是我没有找到而已,我也会继续去寻找。就现在看来,没有找到这方面好的资料。
 
     我现在觉得这是不可思议的一个做法。对象的设计,应该是从业务的分析和业务逻辑中来,和设计没有那么紧密的关系。应该是由设计觉得实现,不应该由实现决定设计。一种实现或是一种框架,不管功能是否强大,都不能“绑架”设计,要设计“屈从”,这是框架设计的一个基本原则。
 
     实际上,一个表对应一个实体对象是很多情况下一个很自然的选择,但并不是必须的做法,如果限制了一定要这么设计实现,那就是非常荒谬的。我经常面向的领域和客户,经常面对的场景里,一个对象拆成几个表是非常有可能的事情。所以,ORM应该支持这种场景。
 
     从另外一个方面看,一个表对应一个实体类是一个有欠考虑的理念。当然,ORM如果支持一个类映射多个表,复杂度增大了很多,用起来也更困难了。没办法,想做通用的东西,肯定比转做一个领域和业务要困难啊。
 
     我本来就不喜欢ORM这东西,这让我更加讨厌Hibernate这类ORM框架,为此特意找了一些网上的资料,觉得这东西还是很不错的,尤其是一些需求简单的场景里,但是支持它的一些说法和理由却站不住脚:
 
     有人说: Hibernate出现的目的,是为了可以让我们这些写代码的,可以更集中精力处理业务代码,而不是把心思放在怎么构建SQL语句。
 
      我的意见: SQL本身也就是体现业务逻辑的。一个产品,本身包含的不仅有功能需求,还有效率、存储方面等等需求。
 
     有人说: 在还没有O/R MAPPING之前,我们在团队开发的时候,实现一个业务逻辑前的事情,就是跑去问DBA或者找系统的数据库 字典,要先把这个逻辑所用到的字段类型、大小、约束都搞清楚,才能开始做编码工作,因为我们需要构建特定的SQL语句、在代码放入各种的逻辑判断…… 
     在有了O/R MAPPING之后,这种现象才得到基本解脱,因为我们要操作表里的数据,只需要直接对映射类操作即可,O/R MAPPING会自动生成所需要的SQL语句……
 
     我的意见: 类型、大小、约束和需要在代码里放入的逻辑判断本身也是业务逻辑的一个部分。不管你用何种理念和工具,都要考虑和面对的。
 
     有人说: 不使用ORM,那么多的get/set多烦人啊,写那些SQL多烦人啊。而且不容易维护。
 
     我的意见: 即便不使用现有的ORM,也肯定会采用面向对象的方式,把数据库的对象和业务对象封装起来给上层使用。业务层面看到的,也是非常清晰的存、取功能调用而已。不会到处都是JDBC的调用和ResultSet的set和get,更不会SQL满天飞。这在一定程度上其实和Hibernate、MyBatis差不多,但是因为不用考虑通用性,所以设计实现起来比较容易,且都是根据自己产品需要来设计,量体裁衣,最最适合自己的产品使用。
     另外说到写SQL,我认为,写好SQL是设计和实现人员的基本功,不能在这里偷懒。我觉得有个人说的(忘了是谁了):“SQL是丑陋的,难以理解的。”这句话是站不住脚的。如果SQL是邪恶的,那么JNI是什么样的呢?SQL是一门非常精炼和优雅的语言,更是一门艺术。SQL中蕴藏了非常简练干净、清晰的概念,非常稳定的架构。
 
     我不会只是从效率方面考虑问题,我更多的考虑是:
      对象应该从业务的分析中来,对象和数据库表毫无关系,对象应该能够从数据存储层取出来,应该能通过存储层保存起来------至于什么表格式等等,都不影响这些上层设计。从数据库表产生实体对象很糟糕;从实体对象产生表结构也一样不好。如上一条所说,对象从业务中来;表的设计,是要根据对象的设计和数据库自身的特点、产品或项目的需求(例如效率需求和不同数据库自身的不同特性)而来的。
      一个项目和产品,很多时候就是应该设计师、实现者和DBA共同努力来做好的,或者另外一种情况,一个团队里,本身就应该有一个或几个精通数据库或SQL的人,来一起做,不能因为说“SQL我不熟悉”或者“写好SQL太困难”为理由,对效率和存储方面的需求视而不见。或者简单的说“OO和关系数据库直接由天然阻抗”。做好数据持久层,一定是需要熟悉或精通数据库和SQL的人。
 
     或者,你做一个对效率、存储、持续性都没有什么要求的项目或产品,那另当别论。又或者经过一段时间的学习和体验,我会改变自己现在的看法。
 

hibernate的一些缺陷(转)的更多相关文章

  1. Hibernate映射解析——七种映射关系

    首先我们了解一个名词ORM,全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对 ...

  2. Hibernate 关系映射方式(1)

    来源:本文转载自:http://blog.csdn.net/huangaigang6688/article/details/7761310 Hibernate映射解析——七种映射关系 首先我们了解一个 ...

  3. 从JDBC到hibernate再到mybatis之路

    一.传统的JDBC编程 在java开发中,以前都是通过JDBC(Java Data Base Connectivity)与数据库打交道的,至少在ORM(Object Relational Mappin ...

  4. SSH深度历险(一)深入浅出Hibernate架构(一)-------映射解析——七种映射关系

            ORM,全称是(Object Relational Mapping),即对象关系映射.ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现,这样开发人员就可以把对数据 ...

  5. 【转载】Hibernate关系映射

    1.        单向一对一关联映射(one-to-one): 两个对象之间一对的关系,例如:Person(人)-IdCard(身份证) 有两种策略可以实现一对一的关联映射: *主键关联:即让两个对 ...

  6. 对象-关系映射ORM(Object Relational Mapping)(转)

    ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现 Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件 ...

  7. Web后端 JAVAWeb面试考查知识点

    面试知识点:1:简单讲一下Java的跨平台原理答:由于非跨平台的情况下,对于不同的操作系统,那么就需要开发几套不同程序代码.为了解决这个问题,java通过不同系统,不同版本,不同位数的JVM来屏蔽不同 ...

  8. 《深入浅出MyBatis技术原理与实战》——1.简介,2.入门

    1. 简介 Java程序都是通过JDBC连接数据库,但是只定义了接口规范,具体的实现交给各个数据库厂商去实现,因为每个数据库都有其特殊性.所以JDBC是一种桥接模式. 这里为什么说JDBC是一种桥接模 ...

  9. Hibernate(6)—— 一对多 和 多对多关联关系映射(xml和注解)总结

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XM ...

随机推荐

  1. ThreadLocal类,实例测试,FutureTask类,实例测试。

    1:测试ThreadLocal类,  为每个线程域保存局部变量.例如下面的例子. ThreadLocal为每个线程保存了一个Test对象,  那么当执行线程时,每个线程中的test具有唯一性.某一个线 ...

  2. 1040. 有几个PAT(25)

    原题: https://www.patest.cn/contests/pat-b-practise/1040 思路: 先给大家扔个测试PAPAATTPATTT, 人工查一下这段字符串能组成 34个PA ...

  3. 手把手教你学node.js之一个简单的express应用

    一个简单的express应用 目标 建立一个 lesson1 项目,在其中编写代码.当在浏览器中访问 http://localhost:3000/ 时,输出 Hello World. 挑战 访问 ht ...

  4. MySQL从删库到跑路(一)——MySQL数据库简介

    作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.MySQL简介 1.MySQL简介 MySQL是一个轻量级关系型数据库管理系统,由瑞典MySQL AB公司开发, ...

  5. Java面向对象---重写(Override)与重载(Overload)

    一.重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为. 也就是说 ...

  6. Xshell5 访问虚拟机Ubuntu16.04

    1.Ubuntu安装telnet 安装openbsd-inetd sudo apt-get install openbsd-inetd 安装telnetd sudo apt-get install t ...

  7. Flask 5 模板1

    NOTE 1.VF的作用:生成请求的响应.一般来说请求会改变程序的状态,这种变化会在视图函数中产生. eg.用户在网站中注册了一个新账户,用户在表单中输入电子邮件地址和密码,然后提交到服务器,服务器接 ...

  8. ERROR: cannot launch node of type [robot_pose_publisher/robot_pose_publisher]: robot_pose_publisher

    sudo apt-get install ros-indigo-robot-pose-publisher

  9. python输出日期时间

    import datetime base = datetime.datetime.today() , ): print(base + datetime.timedelta(days=x))

  10. 反射中的 Class.forName() 与 ClassLoader.loadClass() 的区别

    在Java中,类加载器把一个类加载进Java虚拟机中,要经过三个步骤来完成:加载.链接和初始化,其中链接又可以分成验证.准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下 ...