【MyBatis学习笔记】1:两个ORM框架比较,从一个查询例子认识MyBatis

两个ORM框架比较

Hibernate

Hibernate自EJB之后出现,对JDBC的封装程度较高,是全表映射的,需要提供POJO和映射关系(XML或注解)。

Hibernate优点:

  • 映射规则从程序中分离到XML或注解中。
  • 无需管理数据库连接。
  • 一个会话中只要操作Session对象(JDBC需要操作ResultSet、Statement、Connection)。
  • 支持级联、缓存、映射。

Hibernate缺点:

  • 全表映射不便,如更新时还需其它没被更新的字段。
  • 根据不同条件组装SQL不便。
  • 多表联结的复杂SQL不便。
  • 对存储过程支持差。
  • HQL性能较差。

MyBatis

MyBatis是半自动的ORM框架,不仅需要提供POJO和映射关系,还需要书写SQL语句。

MyBatis优点:

  • 可以配置动态SQL。
  • 可以优化SQL。
  • 对存储过程支持好。
  • 对复杂的和需要优化性能的SQL实现较方便。
  • SQL写在XML里,相比JDBC,能解除SQL与程序代码的耦合。

MyBatis缺点:

  • 配置比Hibernate更繁杂。
  • SQL语句依赖于数据库,导致数据库移植性差。

认识MyBatis的基本构成

  • SqlSessionFactory:这是一个用来创建SqlSession会话对象的工厂接口,它常使用的实现类是DefaultSqlSessionFactory,但这个实现类往往对使用者透明。
  • SqlSessionFactoryBuilder:这个类的对象是直接new出来的,用它的build()方法,传入MyBatis配置信息的输入流就可以建立前面的工厂对象了。
  • SqlSession:类似于Hibernate的Session,它也是指和数据库交互的会话,不过它是一个接口。它的实现类的对象可以直接反射接口里的方法,也可以获取映射器接口实现对象,然后用里面的方法。
  • *Mapper:映射器,由一个接口和一个XML映射文件组成,其中在XML映射文件中会指明相应的映射器接口是哪个,并在里面给出要使用的SQL语句。这个XML映射文件又会被注册到MyBatis配置文件中。所以只要读取配置文件,就能获取到MyBatis相关的一切配置。

映射器也可以用一个接口和相应的Annotation注解实现,但这种方式可读性差,不适合复杂的SQL。

MyBatis的下载和在IDEA下的使用

获取MyBatis

MyBatis的JAR包可以在GitHub上下载,我下载了两天一直下载失败,最后群里的好心人帮下载了。下载好解压后将其核心JAR包和其中的依赖JAR包一并加载到工程里即可。
这里写图片描述

配置IDEA数据库连接

这里写图片描述

有关SQL方言

如果在后面使用时写SQL时出现:
这里写图片描述
只要Alt+Enter配置一下方言即可:
这里写图片描述

一个查询的例子

目录结构

这里写图片描述

创建数据库表

这里写图片描述

model.Student(实体类)

只记录其属性,还要提供无参构造器和getter、setter方法。

private Integer id;
private String stuName;

mapper.StudentMapper(映射器接口)

package mapper;

import model.Student;

//Student类的映射器接口
public interface StudentMapper {
    Student getStudent(int id);
}

mapper/StudentMapper.xml(映射文件)

<?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="mapper.StudentMapper">
    <!--用select元素定义一个查询SQL,id用接口中的方法名-->
    <!--parameterType指定传入的参数类型,resultType指定返回的参数类型,参数类型可用别名(配置文件中定义的)-->
    <select id="getStudent" parameterType="int" resultType="stu">
        SELECT
            id,
            name AS stuName
        FROM student
        WHERE id = #{id}
    </select>
</mapper>

对这里独特的SQL语句进行一下解释:

SELECT
    id, #这里相当于id AS id
    name AS stuName #这里stuName是模型类的属性,name则是实际数据库中表的列
FROM student
WHERE id = #{id} #这里#{}内的id是传入给getStudent函数的参数名称

注意,不能在映射文件中为SQL打上这些注释(所以拿出来解释),不然会报错。

mybatis-config.xml(配置文件)

<?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>
    <!--为实体类定义别名,这样后面在MyBatis上下文提到这个实体类就不用这么长的完整类名了-->
    <typeAliases>
        <typeAlias type="model.Student" alias="stu"/>
    </typeAliases>
    <!--提供数据库信息,默认使用development数据库构建环境-->
    <environments default="development">
        <environment id="development">
            <!--使用JDBC事务管理-->
            <transactionManager type="JDBC"/>
            <!--使用连接池方式来获取连接对象-->
            <dataSource type="POOLED">
                <!--数据库驱动-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接字符串-->
                <property name="url" value="jdbc:mysql://localhost:3306/test_mbts"/>
                <!--用户名-->
                <property name="username" value="root"/>
                <!--密码-->
                <property name="password" value="3838438"/>
            </dataSource>
        </environment>
    </environments>
    <!--注册映射器(只指明xml映射文件,而相应的映射器接口会从映射文件中获取)-->
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>
</configuration>

Main(含main方法的主类)

import model.Student;
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 java.io.IOException;
import java.io.InputStream;

public class Main {

    public static void main(String[] args) {
        //一个打开的SqlSession接口的实现类对象将接受用户的需求,将需求提供给底层的Executor接口完成操作
        //这里拿出try块声明是为了在finally块中对其正常关闭
        SqlSession sqlSession = null;
        try {
            //读取XML配置文件信息到输入流,配置文件中已经注册了映射器(Mapper)
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            //利用配置信息建立SqlSessionFactory(工厂接口)的实现类对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //获取打开的SqlSession对象
            sqlSession = sqlSessionFactory.openSession();
            //不用获取映射器,用iBatis遗留的方式,即调用SqlSession对象的方法
            //第一个参数字符串是映射器配置文件中的"namespace"拼接"id",即"接口的全限名.使用的方法名"
            //如果这个方法是唯一的,可以只写方法名
            Student student = sqlSession.selectOne("mapper.StudentMapper.getStudent", 2);
            System.out.println(student.getId() + "," + student.getStuName());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //在finally块中关闭打开的SqlSession对象
            if (null != sqlSession)
                sqlSession.close();
        }

    }
}

因为这个例子只是做了查询,所以不用在try-catch块里考虑commit提交和rollback回退。

运行结果

这里写图片描述
log4j的日志警告后面再学吧。

猜你喜欢

转载自blog.csdn.net/shu15121856/article/details/80999162