谈谈MyBatis和Hibernate之间的区别

书籍参考:《JavaEE互联网轻量级框架整合开发》    ——作者:杨开振     电子工业出版社

参考博客:https://blog.csdn.net/firejuly/article/details/8190229

MyBatis和Hibernate同为ORM框架,它们都有各自的特点,都是目前市面上比较流行的Java持久层框架,那么它们之间有什么不同,还有它们各自的优点和缺点又在哪里呢,下面慢慢道来。

 

MyBatis的优势在于灵活,它几乎可以代替JDBC,同时提供了接口编程,目前Mybatis的数据访问层DAO(Data Access Object)是不需要实现类的,它只需要一个接口和XML(或注解)。Mybatis提供自动映射,动态SQL,级联,缓存,注解,代码和SQL分离等特性,使用方便,同时也可以对SQL进行优化。因为它具有封装少,映射多样化,支持存储过程,可以进行SQL优化等特点,使得它现在成为Java互联网中首选的持久层框架

Hibernate也有它无可替代的优势,由于Mybatis和Hibernate都是持久层框架,都会涉及数据库,所以先定义一个数据库表——角色表(t_role)

根据这个角色表,我们再创建一个POJO和这张表对应起来

public class Role {
  private Integer id;
  private String roleName;
  private String note;
  /** setter and getter**/
}

 无论是Mybatis还是Hibernate都是依靠某种方法,将数据库的表和POJO映射起来的,这样程序猿就可以操作POJO来完成相关的逻辑了。

要将POJO和数据库映射起来需要给这些框架提供映射规则,所以下一步要提供映射的规则,如图

扫描二维码关注公众号,回复: 5465897 查看本文章

在Mybatis或者Hibernate中都可以同XML或注解提供映射规则,这里采用XML方式

我们把POJO对象和数据库表相互映射的框架成为对象关系映射(Object Relational Mapping,俗称ORM)框架。Mybatis和Hibernate都是ORM框架,只是Hibernate是完全面向POJO的,而Mybatis则不是。

Hibernate基本不再需要编程SQL就可以通过映射关系来操作数据库,是一种全表映射的体现。而Mybatis则需要我们提供SQL去运行

先看看Hibernate将POJO和数据库表对应的映射文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<class name="com.learn.chapter1.pojo.Role" table="t_role">
		<id name="id" type="Interger" >
			<column name="id" />
			<generatot class="identity"/>
		</id>
		<property name="roleName" type="string">
			<column name="role_name" />
		</property>
		<property name="note" type="string">
			<column name="note"/>
		</property>
	</class>
</hibernate-configuration>

首先,对POJO和表t_role进行了映射配置,把两者映射起来了。然后,对POJO进行操作,从而影响t_role表的数据,比如对其增删查改,如下代码所示

Session session=null;
	Transaction tx=null;
	try{
		//打开Session
		session=HibernateUtil.getSessionFactory().openSession();
		//开启事务
		tx=session.beginTransaction();
		//POJO
		//增加
		Role role=new Role();
		role.setRoleName("rolename1");
		role.setNote("note1");
		session.save(role);
		//查询
		Role role2=(Role)session.get(Role.class, 1);
		//修改
		role2.setNote("备注");
		session.update(role2);
		//删除
		session.delete(role2);
		tx.commit();
	}catch(Exception ex){
		if(tx != null && tx.isActive()){
			tx.rollback();
		}
		ex.printStackTrace();
	}final{
		if(session != null && session.isOpen()){
			session.close();
		}
	}

这里我们并没有看到SQL语句,因为Hibernate会根据映射关系来生成对应的SQL语句,程序猿不必精通SQL语句,只要懂得操作POJO就能够操作对应的数据库表了。

这在管理系统时代是十分有利的。因为对于管理系统而言,首先在于实现业务逻辑,然后才是性能,所以Hibernate成为了那个时代的主流持久框架


Mybatis与Hibernate不同在于,Mybatis不屏蔽SQL语句,优势在于程序猿可以自己制定SQL语句,无需Hibernate自动生成规则,这样能够更加精确地定义SQL,从而优化性能。更符合目前移动互联网高并发,大数据,高性能,高响应的要求。

与Hibernate一样,Mybatis也需要一个映射文件把POJO和数据库对应起来,如下代码所示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.learn.chapter1.mapper.RoleMapper">
    	<resultMap id="roleMap" type="com.learn.chapter1.pojo.Role" >
    		<id property="id" column="id"/>
    		<result property="roleName" column="role_name"/>
    		<result property="note" column="note"/>
    	</resultMap>
    	
    	<select id="getRole" resultMap="roleMap">
    		select id,role_name,note from t_role where id = #{id}
    	</select>
    	
    	<delete id="deleteRole" parameterType="int">
    		delete from t_role where id = #{id}
    	</delete>
    	
    	<insert id="insertRole" parameterType="com.learn.chapter1.pojo.Role">
    		insert into t_role(role_name,note) values (#{roleName},#{note})
    	</insert>
    	
    	<update id="update" parameterType="com.learn.chapter1.pojo.Role">
    		update t_role
    		role_name = #{roleName}
    		note = #{note}
    		where id= #{id}
    	</update>
    </mapper>

这里ResultMap元素用于定义映射规则,正式开发时候为了方便我们会使POJO和数据库字段之间满足一定规则,完成自动映射去省略掉ResultMap减轻开发量。

这里得注意,mapper元素中的namespace属性,它要和一个接口的全限定名一致,而里面的SQL的id也需要和接口定义的方法完全一致,如下定义一个接口用于文件映射

package com.learn.chapter1.mapper;
import com.learn.chapter1.pojo.Role;

public interface RoleMapper {
	public Role getRole(int id);
	public int deleteRole(int id);
	public int insertRole(Role role);
	public int updateRole(Role role);
}

定义好了接口,按我们以前的做法,是需要再为接口定义一个实现类。但是,在使用了Mybatis之后,就不需要再定义实现类了。完成增删查改的代码如下

SqlSession sqlSession=null;
	try{
		sqlSession=MyBatisUtil.getSqlSession();
		RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
		//查询
		Role role=roleMapper.getRole(1);
		//更新
		role.setRoleName("new name");
		roleMapper.updateRole(role);
		//插入
		Role role2=new Role();
		role2.setRoleName("role2");
		role2.setNote("备注");
		roleMapper.insertRole(role);
		//删除
		roleMapper.deleteRole(5);
		sqlSession.commit();
	}catch(Exception ex){
		ex.printStackTrace();
		if(sqlSession!=null){
			sqlSession.rollback();
		}
	}finally{
		if(sqlSession!=null){
			sqlSession.close();
		}
	}

比对一下显然MyBatis在业务逻辑上和Hibernate是大同小异的。其区别在于Mybatis需要提供接口和SQL语句,这意味着它的工作量会比Hibernate大,但是由于可以自定义SQL,映射关系,所以其灵活性,可优化性就超过了Hibernate。在互联网时代可优化性和灵活性是十分重要的,因为一条SQL语句的性能可能相差十几倍或几十倍,这对于互联网系统是十分重要的

MyBatis和Hibernate的区别

在映射层而言,hibernate配置不需要接口和SQL,而Mybatis是需要的。

对于Hibernate而言,不需要编写大量的SQL,就可以完成映射,同时提供日志,缓存,级联等特性,此外还提供HQL对POJO进行操作,使用十分方便,但是它也有致命缺陷。

由于无需SQL,当多表关联超过3个时候,Hibernate的级联会造成太多性能的丢失,而且当关联的表多的时候,关联字段会根据特定的条件变化而变化,Hibernate无法支持这样的变化。性能最是关键,在互联网时代,如果响应过慢,会操作用户的丢失。

以上的问题,Mybatis就可以解决了,mybatis可以灵活定义查询语句,满足各种需求和性能优化的需要,这些是十分重要。但是Mybatis也有它的缺陷,Mybatis的工作量会比Hibernate大,通过手工编码,工作量会相对大些。

总结下来,对于性能要求不苛刻的系统推荐使用Hibernate;对于性能要求高,响应快,灵活的系统推荐使用Mybatis。

猜你喜欢

转载自blog.csdn.net/weixin_41866960/article/details/84843749