mybatis和hibernate 对比

来源:互联网 发布:工业数据采集 求 编辑:程序博客网 时间:2024/05/18 20:10

mybatis和hibernate

 第一步, 首先让我们对mybatis和hibernate对比了解下         

1、 Hibernate :Hibernate 是当前非常流行的ORM框架,对数据库结构提供了较为完整的封装,都是为了简化Dao层的操作。
    Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力点在于POJO 与SQL之间的映射关系,都是为了简化Dao层的操作。

2、Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生 成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是  
    差不多的。Hibernate和MyBatis都支持JDBC和JTA事务处理。

3、Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓存方 案,创建适配器来完全覆盖缓存行为,一般在这里的话我们用encache和mybatis和spring集成比较多,这个时候你可以你学习下encache也可以去了解小分布式缓存mencached 还有oschache都可以学习下。

   MyBatis 参考资料官网:http://www.mybatis.org/core/zh/index.html
   Hibernate参考资料: http://docs.jboss.org/hibernate/core/3.6/reference/zh-CN/html_single/
   不同点:
1、hibernate是全自动,而mybatis是半自动。
   Hibernate完全实现了对JDBC的封装,可看成"全自动洗衣机".调用一个save()方法就能实现插入操作,完全不需要写sql.当然,它也支持类似sql的hql语句.ibatis需要自己写sql,但是sql写在配置文件(.xml)文件里面,可看成"半自动洗衣机".mybatis初级阶段可理解成就是ibatis.
      
2、hibernate不怎么需要写sql,而mybatis需要把sql写在配置文件里面。

3、 hibernate数据库移植性和扩展性远大于mybatis,维护性比较好。
    Mybatis由于所有SQL都是依赖数据库书写的,所以扩展性,迁移性比较差,成本很高。Hibernate与数据库具体的关联都在XML中,所以HQL对具体是用什么数据库并不是很关心,大大降低了对象与数据库(oracle、mysql等)的耦合性。
       
4、hibernate开发速度比mybatis相对快点
   Hibernate的开发难度要大于Mybatis。主要由于Hibernate比较复杂、庞大,学习周期较长。
   而Mybatis则相对简单一些,并且Mybatis主要依赖于sql的书写,让开发者感觉更熟悉。
   Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。
   针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。

5、 hibernate拥有完整的日志系统,mybatis则欠缺一些。
    hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。 

6、mybatis相比hibernate需要关心很多细节
   hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。

7、hibernate缓存机制比mybatis强大
     
   Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行严格管理。

   Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。

   MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

   默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

  字面上看就是这样。这个简单语句的效果如下:

  映射语句文件中的所有 select 语句将会被缓存。
  映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改

8、sql直接优化上,mybatis要比hibernate方便很多
   由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。

9、mybait比hibernate更加灵活,驾驭型更好

  Mybatis优势
  MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  MyBatis容易掌握,而Hibernate门槛较高。
  Hibernate优势
  Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。

第二步 让我来介绍下初学者怎么快速更好的使用mybatis这个框架 


     使用mybatis的话,每个Dao就对于一个相应的xml文件,我来给个例子个大家看,先要配置好环境。在application.xml里面
[html] view plaincopyprint?
  1. <!-- c3p0 connection pool configuration 数据库的配置 -->  
  2.     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
  3.         destroy-method="close">  
  4.         <property name="driverClass" value="${jdbc.driverClass}" />       <!-- 数据库驱动 -->  
  5.         <property name="jdbcUrl" value="${jdbc.url}" />       <!-- 连接URL串 -->  
  6.         <property name="user" value="${jdbc.user}" />     <!-- 连接用户名 -->  
  7.         <property name="password" value="${jdbc.password}" />     <!-- 连接密码 -->  
  8.         <property name="initialPoolSize" value="${jdbc.initialPoolSize}" />       <!-- 初始化连接池时连接数量为5个 -->  
  9.         <property name="minPoolSize" value="${jdbc.minPoolSize}" />       <!-- 允许最小连接数量为5个 -->  
  10.         <property name="maxPoolSize" value="${jdbc.maxPoolSize}" />       <!-- 允许最大连接数量为20个 -->  
  11.         <property name="numHelperThreads" value="20" />           <!-- 允许最大连接数量为20个 -->  
  12.         <property name="maxStatements" value="100" />     <!-- 允许连接池最大生成100个PreparedStatement对象 -->  
  13.         <property name="maxIdleTime" value="3600" />      <!-- 连接有效时间,连接超过3600秒未使用,则该连接丢弃 -->  
  14.         <property name="acquireIncrement" value="2" />        <!-- 连接用完时,一次产生的新连接步进值为2 -->  
  15.         <property name="acquireRetryAttempts" value="5" />        <!-- 获取连接失败后再尝试10次,再失败则返回DAOException异常 -->  
  16.         <property name="acquireRetryDelay" value="600" />     <!-- 获取下一次连接时最短间隔600毫秒,有助于提高性能 -->  
  17.         <property name="testConnectionOnCheckin" value="true" />      <!-- 检查连接的有效性,此处小弟不是很懂什么意思 -->  
  18.         <property name="idleConnectionTestPeriod" value="1200" />     <!-- 每个1200秒检查连接对象状态 -->  
  19.         <property name="checkoutTimeout" value="10000" />     <!-- 获取新连接的超时时间为10000毫秒 -->  
  20.     </bean>  
  21.   
  22.     <!-- 创建SqlSessionFactory,同时指定数据源 -->  
  23.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  24.         <property name="dataSource" ref="dataSource" />  
  25.     </bean>  
  26.   
  27.     <!-- 配置事务管理器 -->  
  28.     <bean id="transactionManager"  
  29.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  30.         <property name="dataSource" ref="dataSource" />  
  31.     </bean>  
  32.   
  33.     <!--创建数据映射器,数据映射器必须为接口 -->  
  34.     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
  35.         <property name="annotationClass" value="org.springframework.stereotype.Repository" />  
  36.         <property name="basePackage" value="com.shishuo.studio.dao" />  
  37.     </bean>  

然后我在dao层写个类

 
[html] view plaincopyprint?
  1. package com.shishuo.studio.dao;  
  2. import java.util.List;  
  3. import org.apache.ibatis.annotations.Param;  
  4. import org.springframework.stereotype.Repository;  
  5. import com.shishuo.studio.entity.TagSkill;  
  6. import com.shishuo.studio.entity.vo.TagSkillVo;  
  7. @Repository  
  8. public interface TagSkillDao {  
  9.     /**  
  10.      * 增加  
  11.      *   
  12.      * @param tagSkill  
  13.      * @return  
  14.      */  
  15.     public int addTagSkill(TagSkill tagSkill);  
  16.   
  17.     /**  
  18.      * 删除  
  19.      *   
  20.      * @param skillId  
  21.      * @return  
  22.      */  
  23.     public int deleteTagSkill(@Param("skillId") long skillId);  
  24.   
  25.     /**  
  26.      *   
  27.      * 通过SkillId修改名字  
  28.      */  
  29.     public int updateNameBySkillId(@Param("skillId") long skillId,  
  30.             @Param("name") String name);  
  31.   
  32.     /**  
  33.      * 通过Id查询  
  34.      *   
  35.      * @param skillId  
  36.      * @return  
  37.      */  
  38.     public TagSkillVo getTagSkillByTagId(@Param("skillId") long skillId);  
  39.   
  40.     /**  
  41.      * 通过名字查询  
  42.      *   
  43.      * @param name  
  44.      * @param rows  
  45.      * @return  
  46.      */  
  47.     public TagSkillVo getTagSkillByName(@Param("name") String name);  
  48.   
  49.     /**  
  50.      * 通过userId得到所有所有自己的技能  
  51.      *   
  52.      * @param userId  
  53.      * @return  
  54.      */  
  55.     public List<TagSkillVo> getTagSkillListByUserId(@Param("userId") long userId);  
  56. }  
然后再就是对应的XML文件 TagSkill.xml
[html] view plaincopyprint?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  3.   
  4. <mapper namespace="com.shishuo.studio.dao.TagSkillDao">  
  5.   
  6.     <!-- ############################## -->  
  7.     <!-- ######         增加                   ###### -->  
  8.     <!-- ############################## -->  
  9.       
  10.     <insert id="addTagSkill" parameterType="com.shishuo.studio.entity.TagSkill">  
  11.         insert into tag_skill  
  12.         (name,content,status,createTime)  
  13.         values  
  14.         (#{name},#{content},#{status},#{createTime})  
  15.         <selectKey resultType="long" keyProperty="skillId">  
  16.             SELECT LAST_INSERT_ID()   
  17.         </selectKey>  
  18.     </insert>  
  19.       
  20.     <!-- ############################## -->  
  21.     <!-- ######         删除                   ###### -->  
  22.     <!-- ############################## -->  
  23.       
  24.     <delete id="deleteTagSkill" parameterType="Long">  
  25.         delete from tag_skill where skillId=#{skillId}  
  26.     </delete>  
  27.       
  28.     <!-- ############################## -->  
  29.     <!-- ######         修改                   ###### -->  
  30.     <!-- ############################## -->  
  31.       
  32.     <update id="updateNameBySkillId">  
  33.         update tag_skill set name=#{name} where skillId=#{skillId}  
  34.     </update>  
  35.     <!-- ############################## -->  
  36.     <!-- ######         查询                   ###### -->  
  37.     <!-- ############################## -->  
  38.       
  39.     <select id="getTagSkillByTagId" parameterType="Long"  
  40.         resultType="com.shishuo.studio.entity.vo.TagSkillVo">  
  41.         select * from tag_skill where skillId=#{skillId}  
  42.     </select>  
  43.       
  44.     <select id="getTagSkillByName"   
  45.         resultType="com.shishuo.studio.entity.vo.TagSkillVo">  
  46.         select * from tag_skill where name=#{name}   
  47.     </select>  
  48.       
  49.     <select id="getTagSkillListByUserId"   
  50.         resultType="com.shishuo.studio.entity.vo.TagSkillVo">  
  51.         SELECT tags.skillId,tags.name,tags.content,tags.status,tags.createTime FROM shishuo.tag_skill  tags,shishuo.teacher_skill  teas where tags.skillId=teas.tagSkillId and userId=#{userId};  
  52.     </select>  
  53. </mapper>  

使用经验

1、要记得在TagSkillDao这个类前添加@Repository这个注解,实体的意思
2、你发现了没有,在xml文件里面的id在那个dao层类里面对应的方法名,然后就是在那个XML文件里面,resultType这个参数里面和对应方法里面的返回数据类型想匹配,记住,如果方法返回是int,记得写Internet,是包装类型,不然会出错的,如果是返回对象的话,或者返回一个对象的集合,resultType里面就要写这个对象,如果是没有返回的可以不需要写,在dao层里面的方法需要传参数的话,需要写parameterType,但是一定要记住是包装类型,不是基本数据类型,在dao层里面的方法如果是要增加,就传一个对象过来,不需要写注解,如果是通过Id删除的话,比如public int deleteTagSkill(@Param("skillId") long skillId);我们在xml文件里面
[html] view plaincopyprint?
  1. <delete id="deleteTagSkill" parameterType="Long">  
  2.     delete from tag_skill where skillId=#{skillId}  
  3. </delete>  
[html] view plaincopyprint?
  1. public int deleteTagSkill(@Param("skillId") long skillId);  
 这个#{skillId}就相当于我们函数里面的参数skillId,其它的增删改查都类似。
0 0
原创粉丝点击