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