mybatis第一个helloworld

hibernate和mybatis都是orm的框架,首先贴一波自己对于这两个框架的理解,如果有错误欢迎指正:

    使用hibernate可以轻松实现po类到数据库表的映射,而且hibernate封装了sql,将传统的数据库操作更加偏向于面向对象想,开发者在操作数据库时不需要对数据库知识有很多的了解,因为hibernate会自动生成sql语句,这是hibernate的优点同时也是他的缺点,毕竟框架是面向程序开发,考虑到的是大部分使用场景,不可能对于sql语句做很多的优化,但是如果开发者使用hibernate的方法执行自己的sql语句的话,这也不是不可以实现,但是也会和项目整体的架构会有冲突,这也就是hibernate失去了使用他的意义,而mybatis允许开发者使用自己的sql语句,而且用户可以自己调优.,而且hibernate在缓存方面的支持较mybatis更加丰富,hibernate还有自己得日志记录,而mybatis则需要使用第三方日志jar文件,常用的是log4j,个人认为,hibernate和mybatis的使用场景有很大差别,至于使用哪种,完全在于开发者来选择,至于目前软件开发领域极度鄙视ssh追捧springmvc+spring+mybatis,我觉得两者都是很好的框架,关键是在于使用场景,完成所需功能,其实使用哪种开发流程都是一样的.

下面在贴一波,别人关于hibernate和mybatis优缺点的描述:


著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:知乎
1、开发对比开发速度

Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好Hibernate。

开发社区

Hibernate 与Mybatis都是流行的持久层开发框架,但Hibernate开发社区相对多热闹些,支持的工具也多,更新也快,当前最高版本4.1.8。而Mybatis相对平静,工具较少,当前最高版本3.2。

开发工作量

Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。

针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。

2、系统调优对比Hibernate的调优方案
  1. 制定合理的缓存策略;
  2. 尽量使用延迟加载特性;
  3. 采用合理的Session管理机制;
  4. 使用批量抓取,设定合理的批处理参数(batch_size);
  5. 进行合理的O/R映射设计
Mybatis调优方案

MyBatis在Session方面和Hibernate的Session生命周期是一致的,同样需要合理的Session管理机制。MyBatis同样具有二级缓存机制。 MyBatis可以进行详细的SQL优化设计。

SQL优化方面

Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。

Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。

扩展性方面

Hibernate与具体数据库的关联只需在XML文件中配置即可,所有的HQL语句与具体使用的数据库无关,移植性很好。MyBatis项目中所有的SQL语句都是依赖所用的数据库的,所以不同数据库类型的支持不好。

3、对象管理与抓取策略对象管理

Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化 Java 应用中的数据。

换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑 SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。

而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。

抓取策略

Hibernate对实体关联对象的抓取有着良好的机制。对于每一个关联关系都可以详细地设置是否延迟加载,并且提供关联抓取、查询抓取、子查询抓取、批量抓取四种模式。 它是详细配置和处理的。

而Mybatis的延迟加载是全局配置的。

4、缓存机制对比Hibernate缓存

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

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

5、优势对比

Mybatis优势
  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  • MyBatis容易掌握,而Hibernate门槛较高。
Hibernate优势
  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
个人觉得学习都要一个循序渐进的阶段,建议先学习mybatis,毕竟学习成本较低,而且官方有中文说明官方:说明地址:http://www.mybatis.org/mybatis-3/zh/getting-started.html

hibernate说明文档:就不贴了,很好找,直接百度即可

言归正传,第一个hibernate程序,由于我也刚学,网上也很少找到,mybatis关于数据库连接池的代码配置,这里就不贴,不使用数据库连接池了:
第一步:导入jar包:mybatis-3.2.3.jar,数据库驱动,这里采用的是MySQL数据库

第二步,编写po类和映射文件,可以使用映射文件操作数据库,也可使用接口实例实现操作:

po类:

package com.leige.domain;  
  
public class  Student {  
    private Integer sid;  
    private String name;  
    private Integer age;  
              setter..  
               getter...  
}  

sql映射文件:
<?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">  
<!--  命名空间就是实现sql的隔离,把对于一个对象的操作sql语句放在一个命名空间中  
 这里的调用查询就是Student.selectStudentById -->  
<mapper namespace="Student">  
<!--     按照sid查询数据库  
注意在使用简单po类的简单名称时,前提是在configuration中配置了别名   
  <typeAliases>  
        <typeAlias alias="Student" type="com.leige.domain.Student"/>  
    </typeAliases>  
-->  
  <select id="selectStudentById" parameterType="int" resultType="Student">  
       <![CDATA[   
    select * from student where sid = #{sid} 
    ]]>  
     
  </select>  
   <select id="selectStudentByName" parameterType="java.lang.String" resultType="Student">  
   <!--     '%${value}%'表示字符串拼接,注意占位符的名称不能叫做po类的属性名,出了id除外,不然会报错  
   There is no getter for property named 'xxx' in 'class java.lang.String'  
   不过不建议使用,会产生sql注入  
    -->  
       <![CDATA[   
    select * from student where name like '%${value}%' 
    ]]>  
     
  </select>  
    
     
<!--    增加 -->  
  <insert id="insertStudent" parameterType="Student">  
  <!--     配置主键自增返回,必须和插入语句一起执行才能使用  
  order:表示语句相对于insert的执行顺序  
  resultType:返回结果类型,必须配置  
      mysql的函数SELECT LAST_INSERT_ID()可以查询 -->  
      <selectKey keyProperty="sid" order="AFTER" resultType="int">  
             <![CDATA[   
             SELECT LAST_INSERT_ID() 
             ]]>  
      </selectKey>  
        
   <!--    非自增主键返回  
    <selectKey keyProperty="sid" order="AFTER" resultType="java.lang.String">  
             <![CDATA[   
             SELECT UUID() 
             ]]>  
      </selectKey>  
    -->  
      
         <![CDATA[   
    insert into student(sid,name,age) values(#{sid},#{name},#{age}) 
    ]]>  
  </insert>  
    
<!--   删除 -->  
<delete id="deleteStudentById" parameterType="int">  
      <![CDATA[  
      delete from student where sid=#{sid}  
      ]]>  
</delete>  
  
  
<!--   更新 -->  
<delete id="updateStudent" parameterType="Student">  
      <![CDATA[  
      update student set name=#{name},age=#{age} where sid=#{sid}  
      ]]>  
</delete>  
</mapper>  

接口操作实例:
package com.leige.domain;  
  
import java.util.List;  
  
import org.apache.ibatis.annotations.Delete;  
import org.apache.ibatis.annotations.Select;  
import org.apache.ibatis.annotations.SelectKey;  
import org.apache.ibatis.annotations.Update;  
  
  
  
public interface StudentMapper {  
    //id查找  
    @Select("select * from student where sid=#{sid}")  
    public Student selectStudent(Integer id);  
    //添加  
    @SelectKey(before=false,keyProperty="sid",statement="SELECT LAST_INSERT_ID()", resultType =int.class)  
    @Select("insert into student(sid,name,age) values(#{sid},#{name},#{age})")  
    public void addStudent(Student student);  
    //查找多个  
    @Select("select * from student where name like'%${value}%'")  
    public List<Student> selectStudentByName(String name);  
    //删除  
    @Delete("delete from student where sid=#{value}")  
    public void deleteStudentById(Integer sid);  
    //更新  
    @Update("update student set name=#{name},age=#{age} where sid=#{sid}")  
    public void update(Student student);  
}  


<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
  "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  
  <!--   加载jdbcproperties  
 要写在configuration和environment之间   
  -->  
    <properties resource="com/leige/config/jdbcInfo.properties"></properties>  
 <!--    别名声明,告诉mybatis,Student对应的类类型   
 使其能将Student这个字符和Student类对应起来  
 类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余  
 即在任何需要使用com.leige.domain.Student的地方都可以使用Student  
 -->  
    <typeAliases>  
        <typeAlias alias="Student" type="com.leige.domain.Student"/>  
    </typeAliases>  
<!--     环境配置,数据库连接参数 -->  
  <environments default="development">  
    <environment id="development">  
        
      <transactionManager type="JDBC"/>  
      <dataSource type="POOLED">  
        <property name="driver" value="${driver}"/>  
        <property name="url" value="${url}"/>  
        <property name="username" value="${username}"/>  
        <property name="password" value="${password}"/>  
      </dataSource>  
    </environment>  
  </environments>  
  
<!--   将操作sql集合加入配置文件 -->  
  <mappers>  
    <mapper resource="com/leige/domain/StudentMapper.xml"/>  
  </mappers>  
</configuration>  
jdbc配置参数:

driver=com.mysql.jdbc.Driver  
url=jdbc\:mysql\:///test  
username=root  
password=  

第三步编写工具类,减少代码,实现获取会话session和得到操作实例的功能:

package com.leige.test;  
  
import java.io.IOException;  
import java.io.InputStream;  
  
import org.apache.ibatis.io.Resources;  
import org.apache.ibatis.session.SqlSession;  
import org.apache.ibatis.session.SqlSessionFactory;  
import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
import org.junit.Test;  
  
/**  
 * @author sqlsession工具类  
 *  
 */  
public class SqlUtils {  
    static SqlSessionFactory factory;  
    //静态加载session工厂  
    static{  
        InputStream inputStream;  
        try {  
            inputStream = Resources.getResourceAsStream("com/leige/config/configuration.xml");  
            //1:实例化sqlsessionfactory工厂  
            factory= new SqlSessionFactoryBuilder().build(inputStream);  
        } catch (IOException e) {  
  
        }  
  
  
    }  
    public static SqlSession getSession() {  
        try{  
      
        //开启session  
        return factory.openSession();  
        }catch(Exception e){  
              
            throw new RuntimeException(e);  
        }  
    }  
    /**  
     * @param session  
     * @param mapper  
     * @return  
     * 保证会话session一致,所以当做参数传过来  
     */  
    public static Object getmaMapper(SqlSession session,Class mapper){  
      
        //注册映射接口  
        factory.getConfiguration().addMapper(mapper);  
        //返回操作实例  
        return session.getMapper(mapper);  
    }  
  
}  

测试类:

package com.leige.test;  
  
import java.io.InputStream;  
import java.util.List;  
  
import org.apache.ibatis.io.Resources;  
import org.apache.ibatis.session.SqlSession;  
import org.apache.ibatis.session.SqlSessionFactory;  
import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
import org.junit.Test;  
  
import com.leige.domain.Student;  
import com.leige.domain.StudentMapper;  
  
public class App {  
    /**  
     * @throws 根据id查询单个对象  
     */  
    @Test  
    public void fun() throws Exception{  
  
            InputStream inputStream=Resources.getResourceAsStream("configuration.xml");  
            //1:实例化sqlsessionfactory工厂  
            SqlSessionFactory factory= new SqlSessionFactoryBuilder().build(inputStream);  
            //2:注册接口  
            //factory.getConfiguration().addMapper(StudentMapper.class);  
            //3:开启session  
            SqlSession session=factory.openSession();  
            //4:1操作数据库有两种操作方式一种是,命名空间加命名语句执行  
            //System.out.println(session.selectOne("Student.selectStudent",1));  
              
       /*第二种是使用操作接口操作数据库      
        *   但是需要先注册接口,且接口需要用注解声明操作语句  
        * 即在接口上注册执行时所需要的语句@Select("select * from student where sid=#{id}")  
        * */  
            //注册接口  
              factory.getConfiguration().addMapper(StudentMapper.class);  
              //得到映射器实例  
              StudentMapper studentMapper=(StudentMapper) session.getMapper(StudentMapper.class);  
              //查询数据库  
            System.out.println(studentMapper.selectStudent(1));  
            session.close();  
      
    }  
    /**  
     * 测试查找多个  
     */  
    @Test  
    public void testFindByName(){  
      
        try {  
            //通过工具类得到session  
            SqlSession session=SqlUtils.getSession();  
             List<Student> students=null;  
                    //第一种方式:命名空间查找,也可以使用映射实例查找,selectList查找多个  
                    // students=session.selectList("Student.selectStudentByName", "leige");  
                //第二种方式  
               StudentMapper mapper= (StudentMapper) SqlUtils.getmaMapper(session,StudentMapper.class);  
               students=mapper.selectStudentByName("leige");  
       //打印信息  
           for(Student stu:students)  
               System.out.println(stu);  
        } catch (Exception e) {  
            // TODO Auto-generated catch block  
            System.out.println(e);  
        }  
    }  
  
    /**  
     * 测试增加  
     */  
    @Test  
    public void testInsert(){  
        //通过工具类得到session  
    SqlSession session=SqlUtils.getSession();  
    Student student=new Student();  
    student.setAge(22);  
    student.setName("leige3");  
  
    //第一種方式:执行插入,使用xml配置中sql参数  
    //session.insert("Student.insertStudent",student);  
    //第二種插入,使用接口文件中的sql参数  
    StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);  
    mapper.addStudent(student);  
    //输出返回的主键  
    System.out.println(student.getSid());  
    //注意查询的时候不需要提交,做增删改时需要提交才会生效  
    session.commit();  
    //关闭session  
    session.close();  
    }  
      
      
    /**  
     * 测试删除  
     */  
    @Test  
    public void testDelete(){  
        //获得session  
        SqlSession session=SqlUtils.getSession();  
        //第一種方式:执行删除,使用xml配置中sql参数  
        session.delete("Student.deleteStudentById",12);  
        //第二種删除,使用接口文件中的sql参数  
        StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);  
        mapper.deleteStudentById(13);  
        //提交  
        session.commit();  
        //关闭  
        session.close();  
    }  
      
    /**  
     * 测试更新  
     */  
    @Test  
    public void testupdate(){  
        //获得session  
        SqlSession session=SqlUtils.getSession();  
        //这里就不查询数据库了,直接修改得了  
        Student student=new Student();  
        student.setSid(1);  
        student.setAge(21);  
        student.setName("leige23");  
  
        //第一種方式:执行更新,使用xml配置中sql参数  
        //session.update("Student.updateStudent",student);  
        //第二中更新,使用接口文件中的sql参数  
        StudentMapper mapper=(StudentMapper) SqlUtils.getmaMapper(session, StudentMapper.class);  
        mapper.update(student);  
        //提交  
        session.commit();  
        //关闭  
        session.close();  
    }  
}  

创建数据库表,就不用说了


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值