小言_互联网的博客

1.2MyBatis简介和Hibernate简介

403人阅读  评论(0)

MyBatis简介

MyBatis的前身是Apache的开源项目iBatis。iBatis一次来源于internet,和abatis的组合,是一个基于Java持久层架构。2010年这个项目由Apache software foundation迁移到Google code,并更名为MyBatis。2013年11月,MyBatis迁移到Github上,目前由Github提供维护。
MyBatis的优势在于灵活。他几乎可以替代JDBC,同时提供了接口编程。目前MyBatis的数据访问层DAO(Data Access Objects)是不需要实现类的,他只需要一个接口和XML(或者注解)。MyBatis提供自动映射,动态SQL、级联、缓存、注解、代码和SQL分离等特性,使用方便,同时也可以对SQL进行优化。因为其具有封装少、映射多样化、支持存储过程、可以进行SQL优化等特点,使得他取代了Hibernate成为了Java互联网中首选的持久架构。
Hibernate作为一种十分流行的框架,他有其无可替代的优势,这里我们有必要讨论一下它和MyBatis的区别。由于MyBatis和Hibernate都是持久层架构,都会涉及数据库,所以首先定义一个数据库表–角色表(t_role),其结构如图:

根据这个角色表,我们可以用一个POJO(Plain Ordinary Java Object)和这张表定义的字段对应起来,如下:

package com.learn.chapter1.pojo;
public class Role implements java.io.Serializable{
	private Integer id;
	private String roleName;
	private String nate;
	/*
	    setter and getter
	*/
	
}

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

1.2.1 Hibernate简介

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

在MyBatis或者Hibernate中可以通过XML或者是注解提供映射规则,这讨论的是XML方式,因为在MyBatis中注解方式会收到一定的限制,所以MyBatis通常使用XML方式实现映射关系。
我们把POJO对象和数据库表相互映射的框架称为对象关系映射(Object Relational Mapping,ORM,或者O/RM 或者 O/R mapping框架。无论Mybatis或者是Hibernate都可以称为ORM框架,只是Hibernate的设计理念完全是面向POJO的,而MyBatis不是,Hibernate基本不需要编写SQL就可以通过映射关系来操作数据库,是一种全表映射的体现;而Mybatis则不同,他需要我们提供SQL去运行。
Hibernate是将POJO和数据库表对应的映射文件,如代码:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD3.0//EN"
"http://www.hibernate/org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.learn.chapter1.pojo.Role" table="t_role">
		<id name="id" type="java.lang.Interger">
			<column name="id"/>
			<generator class="identity"/>
		</id>
		<property name="roleName" type="string">
			<column name="role_name" length="60" not-null="true" />
		</property>
		<property name="note" type="string">
			<column name="note" length="512" />
		</property>
	</class>
</hibernate-mapping>

首先,对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.setId(1);
	role.setRoleName("rolename1");
	role.setNote("note1");
	session.save(role);//保存
	Role role2=(Role) session.get(Role.class,1);//查询
	role2.setNote("修改备注");
	session.update(role2);//更新
	System.err.println(role2.getRoleName());
	session.delete(role2);//删除
	tx.commit();//提交事务
}catch(Exception ex){
	if(tx!=null&&tx.isActive()){
		tx.rollback();//回滚事务
	}
	ex.printStackTrace();
	
}finally{
	if(session!=null&&session.isOpen()){
		session.close();
	}
}

这里我们没有看到SQL,那是因为Hibernate会根据映射关系来生成对应的SQL,程序员不用精通SQL,只要懂得操作POJO就能操作数据库对应的表了。
这在管理系统时代是十分有利的,因为对于管理系统而言,首先在于实现业务逻辑,然后才是性能,所以Hibernate成为了那个时代的主流持久框架。

1.2.2 MyBatis

在移动互联网时代,MyBatis成为了目前互联网Java持久框架的首选,与Hibernate消除SQL不同,MyBatis不屏蔽SQL.不屏蔽SQL的优势在于,程序员可以自己制定SQL规则,无需Hibernate自动生成规则,这样能够更加精确地定义SQL,从而优化性能。他更符合移动互联网高并发、大数据、高性能、高响应的要求。
与Hibernate一样,MyBatis也需要一个映射文件把POJO和数据库的表对应起来,MyBatis映射文件代码如下:

<?xml version="1.0" encodeing="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" />
		<reuslt 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="updateRole" parameterType="com.learn.chapter1.pojo.Role">
		update t_role set
			role_name=#{roleName},
			note=#{note}
			where id=#{id}
	</update>
	
</mapper>

这里的resultMap元素用于映射规则,而实际上MyBatis在满足一定的规则下,完成自动映射,而增删改查对应着insert delete select update四个元素,十分明了。
注意,mapper元素中的namespace属性,他要和一个接口的全限定名保持一致,而里面的SQL的id也需要和接口定义的方法完全保持一致,定义MyBatis映射文件,代码如下:

package com.learn.chapter1.mpper;
import com.learn.chapter1.pojo.Role;
public interface RoleMapper{
	
	public Role getRole(Integer id);
	
	public int deleteRole(Integer id);
	
	public int insertRole(Role role);
	
	public int updateRole(Role role);
	
}

定义了MyBatis映射文件,或许读者会有一个很大的疑问,就是是否需要定义一个实现类呢?答案是不需要。
完成对角色类的增删改查,代码如下:

SqlSession sqlSession=null;
try{
	sqlSession=MyBatisUtil.getSqlSession();
	RoleMapper roleMapper=sqlSession.getSqlSession(RoleMapper.class);
	Role role=roleMapper.getRole(1);//查询
	System.err.println(role.getROleName());
	role.setRoleName("update_role_name");
	roleMapper.updateRole(role);//更新
	Role role2=new Role();
	role2.setNote("note2");
	role2.setRoleName("role2");
	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的性能可能相差十几倍到几十倍,这对于互联网系统是十分重要的。

1.2.3 Hibernate和MyBatis的区别

Hibernate和MyBatis的增删查改对于业务逻辑层来说大同小异,对于映射层而言Hibernate的配置不需要借口和SQL,相反MyBatis是需要的。对于Hibernate而言,不需要编写大量的SQL,就可以完全映射,同时提供了日志、缓存、级联(级联比MyBatis强大)等特性,此外还提供HQL(Hibernate Query Language)对POJO进行操作,使用十分方便,但是它也有致命的缺陷。
由于无需SQL,当多表关联超过3个的时候,通过Hibernate的级联会造成太多性能的丢失,又或者我现在访问一个财务的表,然后他会关联财产信息表,财产又分为机械、原料等,显然机械和原料的字段是不一样的,这样关联字段只能根据特定的条件变化而变化,而Hibernate无法支持这样的变化。遇到存储过程,Hibernate只能做吧。更为关键的是性能,在管理系统时代,对于性能的要求不是那么苛刻,但是在互联网时代性能就是系统的更本,响应过慢就会丧失客户,试想一下谁会用一个经常需要等待10秒以上的应用呢?
以上的问题MyBatis都可以解决,MyBatis可以自由书写SQL,支持动态SQL、处理列表、动态生成表名、支持存储过程。这样就可以灵活的定义查询语句,满足各类需求和性能优化的需要,这些在互联网系统中是十分重要的。
但是MyBatis也有缺陷。首先,它需要编写SQL和映射规则,其工作量略微大于Hibernate。其次,它支持的工具也很有限,不能像Hibernate那样有许多插件可以帮助生成映射代码和关联关系,而即使使用生成工具,往往也需要开发者经一步简化,MyBatis通过手动编码,工作量相对大些。所以对于性能要求不太苛刻的系统,比如管理系统,ERP等推荐使用Hibernate,对于性能要求高、响应快、灵活的系统则推荐使用MyBatis。


转载:https://blog.csdn.net/Architect_chaser/article/details/105948700
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场