换一个角度去理解Hibernate与Mybatis

作者: Java架构师CAT | 来源:发表于2019-07-19 09:50 被阅读1次

 首先打个广告,我是一名Java架构师,每天都会分享我认为有价值的技术文章,感兴趣的朋友可以关注我,另外,文末有免费的技术资料领取

 其实,一开始直接写SQL用JDBC去连数据库,简单且性能高。但是,随着集成开发对效率和模块化的追求,渐渐形成了框架,目前还在持续发展中。

  正如,一开始人是吃生肉的,后来会烤肉,再发展出鲁、川、粤、苏、闽、浙、湘、徽八大菜系。Mybatis就正如粤菜,还保持一点原汁原味;Hibernate就像川菜,只看到辣椒,都看不到肉了。

分析问题,要从概念出发。

它山之石,可以攻玉。

  做过一段时间的"无代码"开发,即用第三方图形工具进行编码,这些工具更能把概念形象化,以下带着一些问题,去寻找答案。

  一、Hibernate和Mybatis,都在做什么?

  我们先看看定义:

  Hibernate对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行。

  MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。

所以,关键就是映射(Mapping),将一个数据结构映射到数据库中。

  二、何谓数据结构?

  1.在java的Hibernate,Mybatis中理解,数据结构我理解为Java Bean。有4个特点:

  (1)公有的类 

  (2)私有属性

  (3)提供公有的,不带参数的构造方法 

  (4)属性geter/seter封装

  其实,创建不带参数的构造方法,只是为了方便在创建的时候,提供一个空的实例。

Student s = new Student();

   而你也可以创建带1个,2个或更多参数的构造方法,你可以通过这个方法在创建对象时,先装填几个值,后面的值用set放进去。

Student s = new Student(1, "张三", "男", new Date(), "武当山");

 s.setPicture(image);

  2.换一个开发工具去理解数据结构

  做过2个图形化软件的开发(Webmethods,Kettle),通过图形的拖拉完成程序的开发。两个工具都是基于Java开发的,所以能很形象地理解一些概念。以下,用Webmethods的图形,解释数据结构的概念:

  (1)数据库映射成数据结构

  如图,一个异常表。我们可以很方便地从主表到子表,层层关联,形成一个树状结构。

  这个数据结构,不用多解释,你可以很形象得理解,一个数据结构就是一个document的图标,document中可以包含string,int,甚至是object,还可以是一个set<document>的集合。

  往数据结构的赋值,与java就是geter,seter方法,而在图形中就是简单的拉线,可以拉一个或多个值。

  (2)SAP Idoc映射成数据结构

  IDOC是SAP R/3于SAP R/3或其他外部系统交换数据用过的文件格式,可以类似XML的格式存在。通过图形,我们可以很方便理解,数据如何从SAP,XML,数据结构一步步转换的。

  (3)Flat File映射成数据结构

  Flat File即平面文件,可以是txt,csv,json等,如下面的例子:  

name:张三*sex:男*birth:1970-01-01*address:广东省+中山市+火炬区!

name:李四*sex:男*birth:1980-01-01*address:广东省+中山市+石歧区!

name:王五*sex:女*birth:1990-01-01*address:广东省+中山市+南朗镇!

  记录中以(!)叹号分隔,字段以(*)星号分隔,子记录以(+)分隔,这样的格式和json差不多,体积小方便在网络传输。同样,我们可以为其定义一个数据结构,然后通过字段的分割,写入文档中的信息装入数据结构中。

  (4)MIME映射成数据结构

  MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,在互联网传输的数据,都是用这个数据结构。它通过Content-type去识别是什么类型的数据:

  •HTML文档标记:text/html;

  •普通ASCII文档标记:text/html;

  •JPEG图片标记:image/jpeg;

  •GIF图片标记:image/gif;

  •js文档标记:application/javascript;

  •xml文件标记:application/xml;

也就是说,我们可以把任何形状的数据都放进一个数据结构中去,就像JSP页面的请求一样,只是处理的部分都被一些框架封装了,不用我们手工处理而已。

  三、如何实现映射?

  在Hibernate和Mybatis中,所谓映射,就是通过一些配置,把SQL查出来的字段名称和Java Bean的数据结构进行关联。

  1.Hibernate例子

  (1)建立JavaBean,和数据表

(2)建立数据库配置,及引入相关jar包

  这里有个设定比较重要,当hbm2ddl.auto 为 create的时候,每次自动重建表。

<property name="hbm2ddl.auto">create</property>

   (3)建立数据库与JavaBean关联

  (4)实现功能

public class StudentTest {

    private SessionFactory sessionFactory;

    private Session session;

    private Transaction transaction;

    @Before

    public void init() {

        //创建服务注册对象,会直接去读配置文档

        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();

        //创建会话工厂对象

        sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();

        //会话对象

        session = sessionFactory.openSession();

        //开启事物

        transaction = session.beginTransaction();

    }

    @After

    public void destory() {

        //提交事物

        transaction.commit();

        //关闭会话

        session.close();

        //关闭会话工厂

        sessionFactory.close();

    }

    @Test

    public void testSaveStudents() {

        //生成学生对象

        Student student=new Student(1, "张三", "男", "中山");

        session.save(student);

    }

}

  (5)改进

  除了直接配置数据库字段与JavaBean关联外,还可以通过HQL和注解(Annotation)的方式实现关联。

   •HQL

  public void test01_seller() {

    String hql = " from Seller ";

    Query<Seller> query = session.createQuery(hql);

    List<Seller> sellers =  query.list();

    for (Seller seller : sellers) {

      System.out.println(seller);

    }

  }

  •Annotation

@Entity

@Table(name = "T_Students03", schema = "demo")

public class Students03 {

  @Id

  @GeneratedValue(generator = "sid")

  @GenericGenerator(name = "sid", strategy = "assigned")

  @Column(length = 10)

  private String sid;

  @Column(length = 10)

  private String name;

  @Column(length = 10)

  private String gender;

  private Date birthday;

  @Column(length = 10)

  private String major;

  @Embedded

  private Address address;

  ...

  2.mybatis例子

  (1)建立JavaBean,和数据表

  (2)建立数据库配置,及引入相关jar包

  (3)建立数据库与JavaBean关联

  这个关联比Hibernate要复杂一点,它是通过解析SQL的字段名称(可以是别名),来匹配JavaBean的字段。但是,要灵活很多,因为可以直接写SQL,可以使用很多高级的SQL算法,也方便调优。

  (4)实现功能

  在实现功能的时候,需要知道配置文件的路径,需要根据配置文件找到SQL所在的XML文件,需要根据XML文件找到对应的方法,所以命名空间等要设置好,思路要清晰。

  而相对于hibernate来说,实现比较简单,这些都是由框架来实现,只要根据它提供的规则来做事即可。

  (5)改进

  观察以下代码:

comandlist = sqlSession.selectList("Command.queryCommandList",command);

   Command和queryCommandList分别都是XML里面的配置信息,很容易写错,为了强化管理,还可以引入动态代理,接口式编程来完成,此处不再累述。

  四、Hibernate和Mybatis,折射出何种逻辑?

  1.全自动,还是半自动?

  正如,开车一样,Hibernate是全自动,Mybatis是半自动,总有你喜欢的。

  •场景要求。开自动挡的车,对技术的要求比较低,但是适合比较平坦的路面。

  正如前面讲的4个场景,数据库对数据库的插入,SAP对数据库的插入,双方都是结构化的而且,尤其是对于SAP这么致密的数据库结构,很少改动。如果你需要用Java从SAP转换数据到Oracle,那用hibernate,开发是非常快的。

  但是,如果遇到一些莫可名状的数据结构,为分析这些数据而建很多表,你的表结构有可能整天改,用mybatis比较合适,改SQL要方便一点。

•逻辑要求。Hibernate适合数据结构和数据库结构一对一的关联,如果想做ETL分析,数十张表在一起的,逻辑非常复杂,与其在Java bean建立多种关联关系,不如用Mybatis直接写SQL。

  •性能要求。如果单表数据超过千万,还要进行表关联,就不适合把数据都抽出来让Java处理,而是把逻辑写入SQL,进行调优,这时用mybatis就比较合适。

  (2)设计理念

  这里引入,ASP.net中EF三种编程方式Database first ,Model first ,Code first,无谓谁好谁不好,还是要看场景。

•Database First:根据业务需求把表设计好,然后写逻辑,写代码,如早期银行的DB2数据库,信息固定,数据量大,数据库设计非常重要。Mybatis贴近这种模式。

•Model First:先把数据模型设计好,通过模型建表,再写代码。如ETL分析,先用PowerDesigner把数据仓库建好,字段错了马上改,马上更新数据库,数据可以删掉再抽取。

•Code First:先把代码写好,通过工具生成表。目前,ASP.NET就推荐这种模式,而Hibernate也贴近这种模式,业务逻辑优先,对数据库技术依赖少,而作为搞数据库出身的人,比较难接受。

  (3)无代码,还是有代码?

  近期,看到一篇文章说,为什么国外少用Mybatis,多用Hibernate。我们先看2款国外的软件,webmethods,kettle,他们都基于Java开发的可视化变成工具,都是用hibernate做数据操作的。为何?

  因为,hibernate很方便就把数据库的字段对象,转化为业务流中的字段对象。而这些对象,又很容易和图形结合在一起,于是就形成无代码的拖拉式开发。

•webmethods

•Kettle

  这要求对规范的恪守。而从实际上看,webmethods,kettle这两款软件,它们底层维持自身运作的数据库结构,经历多年的版本升级,几乎没变。

  而国内的开发,数据库的搭建,对业务的梳理无章可循,喜欢拍脑袋,说改就改,所以用mybatis比较合适,但是,就出不了像SAP,Webmethods,Kettle这样的专业软件。

  (4)趋于业务,还是趋于技术?

  在无代码和有代码之后,战略布局的问题。

  一个问题:Java开发难,还是SAP开发难?

  我觉得是Java更难一点。因为SAP已经形成一套标准,开发人员更多的是从编程中解放出来,去思考业务逻辑的问题。只是,SAP的费用比较高。你想把钱花在软件上,还是花在培养人上。

  而Java就是不停地重复造轮子,从零搭建系统。但Java的整个生态也在不断推进,从JSP+Servlet,生成Struts2这样的框架,大大加快了开发效率。

讲到最后,我觉得Hibernate是基于规则的编程,而Mybatis是基于配置的编程。你又喜欢哪个呢?

免费分享Java技术资料,关注我后在后台私信我即可免费获得你需要的Java技术资料

原文:https://zhuanlan.zhihu.com/p/74262926作者:白天不懂夜的黑来源:知乎

相关文章

网友评论

    本文标题:换一个角度去理解Hibernate与Mybatis

    本文链接:https://www.haomeiwen.com/subject/ketjlctx.html