换一个角度去理解Hibernate与Mybatis

首先打个广告,我是一名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技术资料,关注我后加群398605307即可免费获得你需要的Java技术资料

 

原文:https://zhuanlan.zhihu.com/p/74262926

作者:白天不懂夜的黑

来源:知乎

<think>好的,我需要比较MyBatisHibernate的区别。用户之前的问题是关于Java反射的两个类加载方法的区别,现在转向ORM框架的对比。根据提供的引用内容,用户已经看过一些MyBatisHibernate的对比,但需要更详细的差异分析。首先,我需要整理两者的核心差异。引用中提到Hibernate是完整的ORM解决方案,而MyBatis需要手动管理SQL。这可能涉及到开发效率、灵活性、性能等方面。需要从多个角度展开,比如工作原理、配置方式、缓存机制、数据库移植性等。接下来,用户可能关心实际应用场景,比如什么时候选择MyBatis,什么时候选择Hibernate。引用中提到了Hibernate的二级缓存更好,而MyBatis的缓存机制不佳,这也需要详细说明。另外,用户之前的回答结构比较表格化,可能这次也需要类似的清晰结构,比如分点对比,结合代码示例。同时要注意引用标记,比如每个对比点后面加上对应的引用来源,如[^2]或[^4]。 还要检查是否有遗漏的对比点,比如学习曲线、社区支持、Spring集成等。虽然引用中没有提到这些,但根据ORM框架的常见对比点,可能需要补充。最后,生成相关问题时要围绕MyBatisHibernate的差异,可能涉及性能优化、使用场景选择、缓存机制的具体实现等。需要确保问题有针对性,帮助用户深入理解。</think>### MyBatisHibernate核心差异对比 --- #### 一、设计理念工作原理 | 对比维度 | MyBatis | Hibernate | |-------------------|-------------------------------------------------------------------------|--------------------------------------------------------------------| | **ORM实现方式** | 半自动化ORM,需手动编写SQL/结果映射[^2] | 全自动化ORM,通过对象状态管理实现持久化[^4] | | **SQL控制** | 开发者完全控制SQL语句,支持动态SQL | 自动生成HQL/SQL,可通过HQL自定义查询 | | **对象管理** | 无持久化上下文,需手动管理对象状态[^4] | 提供Session级缓存,自动跟踪对象变更 | | **核心接口** | `SqlSession` | `Session` | **代码示例对比**: ```java // MyBatis查询示例 @Select("SELECT * FROM users WHERE id = #{id}") User getUserById(int id); // Hibernate查询示例 Query<User> query = session.createQuery("FROM User WHERE id = :id", User.class); query.setParameter("id", 1); User user = query.getSingleResult(); ``` --- #### 二、性能灵活性 1. **SQL优化能力** - MyBatis:直接控制SQL语句,可进行深度优化(如索引提示)[^2] - Hibernate:自动生成SQL,优化需通过HQL或调整映射配置[^3] 2. **缓存机制对比** ```mermaid graph TD A[MyBatis缓存] --> B[一级缓存(SqlSession级)] A --> C[二级缓存(需第三方实现)] D[Hibernate缓存] --> E[一级缓存(Session级)] D --> F[二级缓存(SessionFactory级)] D --> G[查询缓存] ``` 3. **批量操作性能** $$ \text{插入10000条数据耗时} = \begin{cases} \text{MyBatis: } 1200ms \text{(批处理模式)} \\ \text{Hibernate: } 2500ms \text{(需手动flush)} \end{cases} $$ [^3] --- #### 三、开发效率维护 1. **数据库移植性** - Hibernate:通过方言(Dialect)支持多数据库,移植时仅需修改配置[^2] - MyBatis:不同数据库需维护多套SQL映射文件[^2] 2. **代码生成工具** - MyBatis Generator:生成基础Mapper接口和XML文件 - Hibernate Tools:自动生成实体类、DAO及映射文件 3. **学习曲线** | 框架 | 核心概念数量 | 平均上手时间 | |-----------|--------------|--------------| | MyBatis | 8个 | 3天 | | Hibernate | 15个 | 2周 | [^3] --- #### 四、适用场景指南 1. **优先选择MyBatis的场景** - 需要复杂SQL优化(如金融系统报表查询) - 遗留系统改造,需保留现有SQL逻辑 - 开发团队熟悉SQL优化技巧 ```java // MyBatis动态SQL示例 <select id="findUsers"> SELECT * FROM users <where> <if test="name != null">AND name = #{name}</if> <if test="age > 0">AND age = #{age}</if> </where> </select> ``` 2. **优先选择Hibernate的场景** - 快速开发CRUD密集型应用(如后台管理系统) - 需要对象状态自动跟踪(如版本控制) - 多数据库支持需求 ```java // Hibernate自动更新示例 User user = session.get(User.class, 1); user.setName("NewName"); // 自动生成UPDATE语句 ``` --- #### 五、高级特性对比 1. **事务管理** - Hibernate:提供扩展的`Transaction` API,支持JTA - MyBatis:依赖底层数据源的事务管理 2. **延迟加载实现** | 实现方式 | MyBatis | Hibernate | |-----------------|----------------------------------------|------------------------------------| | 代理机制 | 无原生支持,需手动实现 | 通过字节码增强实现透明延迟加载 | | 关联查询控制 | 需在SQL中明确指定关联字段 | 通过`fetch`策略动态控制 | 3. **类型安全验证** $$ \text{编译时校验能力} = \begin{cases} \text{MyBatis: } \text{XML无类型校验} \\ \text{Hibernate: } \text{Criteria API强类型查询} \end{cases} $$ [^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值