MyBatis入门 Mybatis和hibernate的区别 MyBatis相关部分面试题 MyBatis的优缺点

1. 什么是MyBatis?

mybatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。

mybatis 通过 xml或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

2.什么是持久化?

持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。持久化是将程序数据在持久状态和瞬时状态间转换的机制。JDBC就是一种持久化机制。文件IO也是一种持久化机制。

3.什么是持久层?

数据访问层又称为DAL层,有时候也称为是持久层,其功能主要是负责数据库的访问。简单的说法就是实现对数据表的Select(查询),Insert(插入),Update(更新),Delete(删除)等操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。最常见的持久层框架有两个:Hibernate和MyBatis。

4.JDBC编程分析

  4.1 代码回顾

public static void main(String[] args) {
    Connection connection = null;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
        //加载数据库驱动
        Class.forName("com.mysql.jdbc.Driver");
        //通过驱动管理类获取数据库链接
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", " root");
        //定义 sql 语句 ?表示占位符
        String sql = "select * from user where username = ?";
        //获取预处理 statement
        preparedStatement = connection.prepareStatement(sql);
        //设置参数,第一个参数为 sql 语句中参数的序号(从 1 开始),第二个参数为设置的参数值
        preparedStatement.setString(1, "王五");
        //向数据库发出 sql 执行查询,查询出结果集
        resultSet = preparedStatement.executeQuery();
        //遍历查询结果集
        while (resultSet.next()) {
            System.out.println(resultSet.getString("id") + " " + resultSet.getString("username"));
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //释放资源
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    4.2 JDBC缺陷总结

  • 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    • mybatis中自带连接池

  • Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大, sql 变动需要改变java 代码。

    • mybatis中的SQL语句不是写在代码中,而是写在配置文件中

  • 使用 preparedStatement 向占位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。

    • mybatis中的根据不同的参数添加SQL语句中不同条件也在配置文件可以完成

  • 对结果集解析存在硬编码(查询列名), sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便。

    • mybatis中会使用反射将结果集中的数据自动封装到JavaBean对象中

5.MyBatis的整体架构

 

6.MyBatis快速入门

6.1 官网下载 Mybatis 框架

网址:http://www.mybatis.org/mybatis-3/zh/getting-started.html

对应依赖包下载 :https://github.com/mybatis/mybatis-3/releases

6.2 搭建 Mybatis 开发环境

创建工程之前,我们先新建数据库mybatis,并在数据库中新建一张User表,并加一些数据。表结构入下

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `sex` char(1) DEFAULT NULL COMMENT '性别',
  `address` varchar(256) DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8;

6.2.1 创建maven工程

  • 创建 mybatis-day01-demo1 的工程, 工程信息如下:

  • Groupid:com.itttt

  • ArtifactId:mybatis-day01-demo1

  • Packing:jar

6.2.2 pom.xml导入依赖

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itttt</groupId>
    <artifactId>mybatis-day01-demo1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--打包方式-->
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <!--引入相关依赖-->
    <dependencies>
        <!--MyBatis依赖包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>

        <!--MySQL驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
            <scope>runtime</scope>
        </dependency>

        <!--日志包-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>

        <!--测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

6.2.3 创建User

创建com.itttt.domain包,在该包下创建User对象,并添加对应的属性

public class User implements Serializable {
    private Integer id;
    private String username;
    private String birthday;
    private String sex;
    private String address;

    //略 get...set...toString...
}

6.2.4 创建UserMapper接口

创建com.itttt.mapper包,并在该包下创建接口,代码如下:

它其实就是dao层的接口

public interface UserMapper {
    List<User> findAll();
}

6.2.5 创建UserMapper.xml

这个xml配置文件的位置,必须和对应的那个Mapper接口的位置一样。而且其文件名也要和接口名一样

在com.itttt.mapper包下创建UserMapper.xml,并在UserMapper.xml中添加一个select查询结点,代码如下:

<?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.itttt.mapper.UserMapper">
    <!--findAll-->
    <select id="findAll" resultType="com.itheima.domain.User">
        SELECT * FROM  user
    </select>
</mapper>

6.2.6 创建SqlMapConfig.xml

在main/resources下创建SqlMapConfig.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>
    <!--数据源配置-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123"/>
            </dataSource>
        </environment>
    </environments>

    <!--加载映射文件-->
    <mappers>
        <mapper resource="com/itttt/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

6.2.7 为了方便查看日志,在main/resources下创建log4j.properties文件,代码如下

log4j.rootLogger=DEBUG,Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=DEBUG

6.3 编写测试类

在test包下创建com.itttt.test,再在该包下创建MyBatisTest类,代码如下

public class MyBatisTest {

    @Test
    public void testFindAll() throws IOException {
        //读取配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

        //通过SqlSessionBuilder对象构建一个SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = builder.build(is);

        //通过SqlSessionFactory构建一个SqlSession
        SqlSession session = sqlSessionFactory.openSession();

        //通过SqlSession实现增删改查
        UserMapper userMapper = session.getMapper(UserMapper.class);
        List<User> users = userMapper.findAll();

        //打印输出
        for (User user : users) {
            System.out.println(user);
        }
        //关闭资源
        session.close();
        is.close();
    }
}

mybatis入门程序的小结

  1. 引入依赖

  2. 编写一个接口,以及其对应的映射配置文件

    1. 映射配置文件的路径和文件名要和对应的接口一致

    2. 映射配置文件的根标签(mapper)的namespace属性的值要和对应的接口的全限定名一致

    3. 接口中的每一个方法就对应映射配置文件中的一个标签

      1. 标签的id属性就对应方法的方法名

      2. 标签的parameterType属性就对应方法的参数类型

      3. 标签的resultType属性就对应方法的返回值的类型,如果返回值有泛型就对应泛型类型

  3. 编写一个主配置文件

    1. 配置环境

    2. 加载映射配置文件

  4. 在单元测试用例中,编写mybatis的测试代码

 

Mybatis和hibernate的区别

1.编写实现

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

2.性能比较

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

3.执行细节

Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然的面向对象的视角来持久化 Java 应用中的数据。换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑 SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性能调优的时候才需要进行了解。而MyBatis在这一块没有文档说明,用户需要对对象自己进行详细的管理。

4.缓存机制

Hibernate一级缓存是Session缓存,Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消亡。
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

  MyBatis的优点:

Mybatis优势

  • MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
  • MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势:

  • Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
  • Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
  • Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。
  • Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
  • Hibernate功能强大,数据库无关性好,O/R映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
  • MBATIS入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
  • MBATIS的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。

 

MyBatis相关部分面试题:

1.Mybatis比IBatis比较大的几个改进是什么

a.有接口绑定,包括注解绑定sql和xml绑定Sql ,

b.动态sql由原来的节点配置变成OGNL表达式,

c. 在一对一,一对多的时候引进了association,在一对多的时候引入了collection节点,不过都是在resultMap里面配置

2.什么是MyBatis的接口绑定,有什么好处

接口映射就是在IBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,

我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置.

 

3.接口绑定有几种实现方式,分别是怎么实现的?

接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上

@Select@Update等注解里面包含Sql语句来绑定,另外一种就是通过xml里面写SQL来绑定,

在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.

 

4.什么情况下用注解绑定,什么情况下用xml绑定

当Sql语句比较简单时候,用注解绑定,

当SQL语句比较复杂时候,用xml绑定,一般用xml绑定的比较多

 

5.MyBatis实现一对一有几种方式?具体怎么操作的

有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,

通过在resultMap里面配置association节点配置一对一的类就可以完成;

 

嵌套查询是先查一个表,根据这个表里面

的结果的外键id,去再另外一个表里面查询数据,也是通过association配置,但另外一个表

的查询通过select属性配置

 

6.MyBatis实现一对多有几种方式,怎么操作的

有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次,通过在resultMap里面配

置collection节点配置一对多的类就可以完成;

 

嵌套查询是先查一个表,根据这个表里面的

结果的外键id,去再另外一个表里面查询数据,也是通过配置collection,但另外一个表的

查询通过select节点配置

 

7.MyBatis里面的动态Sql是怎么设定的?用什么语法?

MyBatis里面的动态Sql一般是通过if节点来实现,通过OGNL语法来实现,但是如果要写的完

整,必须配合where,trim节点,where节点是判断包含节点有内容就插入where,否则不插

入,trim节点是用来判断如果动态语句是以and 或or开始,那么会自动把这个and或者or取

 

8.IBatis和MyBatis在核心处理类分别叫什么

IBatis里面的核心处理类交SqlMapClient,

MyBatis里面的核心处理类叫做SqlSession

 

9.IBatis和MyBatis在细节上的不同有哪些

在sql里面变量命名有原来的#变量# 变成了#{变量}

原来的$变量$变成了${变量},

原来在sql节点里面的class都换名字交type

原来的queryForObject queryForList 变成了selectOne selectList

原来的别名设置在映射文件里面放在了核心配置文件里

 

10.讲下MyBatis的缓存

MyBatis的缓存分为一级缓存和二级缓存,

一级缓存放在session里面,默认就有,二级缓存放在它的命名空间里,默认是打开的,

使用二级缓存属性类需要实现Serializable序列化接

口(可用来保存对象的状态),可在它的映射文件中配置<cache/>

 

11.MyBatis(IBatis)的好处是什么

ibatis把sql语句从Java源程序中独立出来,

放在单独的XML文件中编写,给程序的维护带来了很大便利。

ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,

大大简化了Java数据库编程的重复工作。

 

因为Ibatis需要程序员自己去编写sql语句,

程序员可以结合数据库自身的特点灵活控制sql语句,

因此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。

 

MyBatis的优点:

(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;

(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。

(4)能够与Spring很好的集成;

(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
 

MyBatis的缺点:

(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值