Hibernate 和 MyBatis 都是持久层框架,都会涉及数据库,所以先定义一个数据库表,先从代码编写角度对比两者。
新建一个 POJO 类,和表的字段对应起来。
package com.learn.chapter1.pojo;
implements java.io.Serializable;
public class Role implements Serializable{
private Integer id;
private String roleName;
private String note;
/*下面是setter和getter方法,可自动生成,此处略去不写*/
}
一、Hibernate 实现
Hibernate 基本不需要编写 SQL 就可通过映射关系来操作数据库,是一种全表映射的体现。Hibernate 是将 POJO 和数据库表对应的映射文件。
Hibernate 映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.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.Integer">
<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 表的数据,比如对其增、删、改、查可按照下述代码操作。
Hibernate 通过 Session 操作数据库数据
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.out.println(role2.getRoleName());
session.delete(role2);//删除
tx.commit();//提交事务
}catch(Exception e){
if(tx != null && tx.isActive()){
tx.rollback();//回滚事务
}
e.printStackTrace();
}finally{
if(session != null && session.isOpen()){
session.close();
}
}
二 、MyBatis 实现
MyBatis 映射文件
<?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) value (#{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、update、select 四个元素。
注意,mapper 元素中的 namespace 属性,它要和一个接口中的全限定名保持一致,而里面的 SQL 的 id 也需要和接口定义的方法完全保持一致,定义 MyBatis 映射文件。
MyBatis 接口文件
package com.learn.chapter1.mapper;
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.getMapper(RoleMapper.class);
Role role = roleMapper.getRole(1);//查询
System.out.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 e){
e.printStackTrace();
if(sqlSession != null){
sqlSession.rollback();//回滚事务
}
}finally{//关闭连接
if(sqlSession != null){
sqlSession.close();
}
}
三、Hibernate 和 MyBatis 的区别
Hiberante 和 MyBatis 的增、删、改、查,对于业务逻辑层来说大同小异,对于映射层而言 Hibernate 的配置不需要接口和 SQL,相反 MyBaits 是需要的。对于 Hibernate 而言,不需要编写大量的 SQL,就可以完全映射,同时提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供了 HQL(Hibernate Query Language)对POJO 进行操作,使用十分方便,但是它也有致命的缺陷。由于无需 SQL,当多表关联超过 3 个的时候,通过 Hibernate 的级联就会造成太多性能的丢失。
MyBatis 可以自由书写 SQL、支持动态 SQL、处理列表、动态生成表名、支持存储过程。这样就可以灵活地定义查询语句,满足各类需求和性能优化的需要。MyBatis 也有缺陷。首先他要编写 SQL 和映射规则,其工作量稍大于 Hibernate。其次,它支持的工具也很有限,不能像 Hibernate 那样有许多的插件可以帮助生成映射代码和关联关系,而即使使用生成工具,往往也需要开发者进一步简化,MyBatis 通过手工编码,工作量相对大些。所以对于性能要求不太苛刻的系统 ,比如管理系统等推荐使用 Hibernate ;而对于性能要求高、响应快、灵活的系统则推荐使用 Mybatis。