MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门

MyBatis学习总结(一)什么是框架/什么是持久层/什么是MyBatis/MyBatis的优缺点/(面试题)MyBatis和Hibernate的区别/MyBatis使用入门

一、持久层技术解决方案

  • 什么是持久层?
      持久是相对于瞬时来说的,其实就是可以把数据固化在硬盘或者磁带一类可以保存很长时间的设备上,不像放在内存中一样断电就消失了。企业应用中数据很重要(各种订单数据、客户数据、库存数据之类的),比应用程序本身更重要,所以需要把数据持久化。
      一般地,持久更为直接的理解就是对数据库的各种操作,如CRUD(增加、删除、修改、查询)等操作,需要将已改变的数据保存起来。
      持久层,就是把持久的动作封装成一个独立的层,这是为了降低功能代码之间的关联,创建一个更清晰的抽象,提高代码的内聚力,降低代码的耦合度(高内聚,低耦合),从而使程序间以及程序内部都能够独立于其他程序,增加程序的可维护性、移植性和可重用性等等。
  • 我们已经学过的持久层技术解决方案包括:JDBC技术Spring的JdbcTemplate(Spring中对JDBC的简单封装)、Apache的DBUtils(也是对JDBC的简单封装)
    然而以上这些都不是框架:JDBC是规范,Spring的JdbcTemplate和Apache的DBUtils都只是工具类。
  • JDBC问题分析:
    • 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
    • sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java代码。
    • 使用 preparedStatement 向占位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
    • 对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便。

因此我们就需要一个持久层的框架来更好地实现需求。

二、框架概述

(一)什么是框架

  • 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
  • 简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。
  • 使用框架的好处:框架封装了很多的细节,使开发者可以使用极简的方式实现功能。大大提高开发效率。

(二)框架要解决的问题

  • 框架要解决的最重要的一个问题是技术整合的问题,在 J2EE 的 框架中,有着各种各样的技术,不同的软件企业需要从 J2EE 中选择不同的技术,这就使得软件企业最终的应用依赖于这些技术,技术自身的复杂性和技术的风险性将会直接对应用造成冲击。而应用是软件企业的核心,是竞争力的关键所在,因此应该将应用自身的设计和具体的实现技术解耦。这样,软件企业的研发将集中在应用的设计上,而不是具体的技术实现,技术实现是应用的底层支撑,它不应该直接对应用产生影响。
  • 框架一般处在低层应用平台(如 J2EE)和高层业务逻辑之间的中间层。

(三)MyBatis 框架概述

  • mybatis 是一个优秀的基于 java持久层框架,它内部封装了 jdbc使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程
  • mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
  • 采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

问:实现持久层的框架有哪些?

答:

  1. Hibernate:全自动的ORM(对象关系映射)框架,可以自动生成SQL语句,自动执行。
  2. MyBatis:半自动的ORM框架,需要我们自己编写SQL语句。

(四)MyBatis的优缺点

优点

  1. 简洁:不用再去编写一堆JDBC代码,代码量大大减少。
  2. 简单易学:MyBatis是最简单的持久化框架,小巧且容易上手。
  3. 灵活:不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,便于统一管理和优化。
  4. 提供XML标签,支持编写动态SQL语句。
  5. 提供映射标签,支持对象与数据库的ORM字段关系映射。
  6. 实现解耦:通过提供DAO层,将SQL语句和程序代码分离,使系统的设计更清晰,方便单元测试,降低了耦合度,提高了可维护性。

缺点

  1. 字段多、关联表多时,SQL语句的编写工作量较大,要求开发人员要熟练掌握SQL语句的编写。
  2. SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

(五)MyBatis和Hibernate的区别【面试题】

相同点

  1. 都属于ORM(对象关系映射)框架
  2. 都属于持久层框架
  3. 都是对JDBC的包装

不同点

  1. 开发工作量方面:Hibernate是全自动的框架,MyBatis是半自动的框架,这是最大的区别。Hibernate因为有良好的映射机制,可以自动生成SQL语句,不必手动编写SQL语句,开发者可以无需担心SQL的生成和结果映射,而是更关注于业务流程;而MyBatis必须手动编写SQL语句以及结果映射(resultMap)。因此,MyBatis较Hibernate的开发工作量大。
  2. 移植性方面:Hibernate具有强大的数据库无关性,可跨数据库使用;而MyBatis的所有SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
  3. SQL优化方面:Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗;而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。
  4. 日志系统方面:Hibernate拥有完整的日志系统,而MyBatis需要依靠log4j来实现。
  5. 开发速度方面:对于大型项目,复杂语句较多,选择MyBatis就会加快许多,其简单易上手,而且语句的管理也比较方便。

三、MyBatis 框架快速入门

(一)创建 Maven 工程

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第1张图片

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第2张图片

(二)官网下载 MyBatis 框架

打开MyBatis官网。
进入选择语言的界面,进入中文版本的开发文档。

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第3张图片
在这里插入图片描述
下载相关的 jar 包或复制 maven 依赖。
MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第4张图片
这里我们使用导入maven依赖的方式,我们所使用的 MyBatis 版本是 3.4.5 版本。

(三)入门案例

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第5张图片

准备数据库:

DROP TABLE IF EXISTS `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 DEFAULT CHARSET=utf8;

INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小王','2018-03-02 15:09:37','女','安徽'),(43,'小二','2018-03-04 11:34:34','女','上海'),(45,'小明','2018-03-04 12:04:06','男','广东'),(46,'杰克','2018-03-07 17:37:26','男','北京'),(48,'小马','2018-03-08 11:44:00','女','北京');

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第6张图片
对应数据表的列名,创建实体类:

import java.util.Date;

public class User implements Serializable{

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

为什么开发中建议实体类要实现Serializable接口?

pom.xml:


<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.0modelVersion>

    <groupId>com.foxgroupId>
    <artifactId>MybatisStudyartifactId>
    <version>1.0-SNAPSHOTversion>
    <packaging>jarpackaging>

    <dependencies>
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.4.5version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.6version>
        dependency>
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.12version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.10version>
        dependency>
    dependencies>
project>

log4j日志配置log4j.properties:

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

编写持久层接口 IUserDao:

import com.fox.pojo.User;
import java.util.List;

//用户的持久层接口
public interface IUserDao {

    //查询所有操作
    List<User> findAll();
}

编写持久层接口的映射文件 IUserDao.xml:

  • 要求:创建位置必须和持久层接口在相同的包中。
  • 名称:必须以持久层接口名称命名文件名,扩展名是.xml
    MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第7张图片

DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.fox.dao.IUserDao">
    
    
    <select id="findAll" resultType="com.fox.pojo.User">
        select * from user;
    select>
mapper>

编写MyBatis核心配置文件SqlMapConfig.xml(名字随便取):


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    
    <environments default="mysql">
        
        <environment id="mysql">
            
            <transactionManager type="JDBC">transactionManager>
            
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                
                <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            dataSource>
        environment>
    environments>

    
    <mappers>
        <mapper resource="com/fox/dao/IUserDao.xml"/>
    mappers>
configuration>

编写测试类:

import com.fox.dao.IUserDao;
import com.fox.pojo.User;
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.InputStream;
import java.util.List;

public class MybatisTest {
    public static void main(String[] args) throws Exception{
        //1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建 SqlSessionFactory 的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3.使用构建者创建工厂对象 SqlSessionFactory
        SqlSessionFactory factory = builder.build(in);
        //4.使用 SqlSessionFactory 生产 SqlSession 对象
        SqlSession session = factory.openSession();
        //5.使用 SqlSession 创建 dao 接口的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //6.使用代理对象执行查询所有方法
        List<User> users = userDao.findAll();
        for(User user : users) {
            System.out.println(user);
        }
        //7.释放资源
        session.close();
        in.close();
    }
}

运行,IDEA输出:
MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第8张图片
注意事项:

  1. 在Mybatis中把持久层的接口名称和映射文件也叫做:Mapper,所以:IUserDao 和 IUserDao.xml 与 IUserMapper 和 IUserMapper.xml 是一样的。
  2. 在idea中创建目录(directory)的时候,它和包(package)是不一样的
    包在创建时:一次性输入com.itheima.dao它是三级结构
    目录在创建时:一次性输入com.itheima.dao是一级目录
    因此我们在创建接口的映射文件时,如果没有package选项,应该一层一层地创建directory。
  3. mybatis的映射配置文件位置必须和dao接口的包结构相同
  4. 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
  5. 映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名

当我们遵从了以上几点之后,我们在开发中就无须再写dao的实现类,因为Mybatis底层使用了JDK动态代理的方式创建代理对象完成了。

我们在实际开发中,都是越简便越好,所以都是采用不写dao实现类的方式,例如XML或者注解的方式。但是Mybatis它是支持写dao实现类的,只是代码十分冗余。

(四)基于注解的 MyBatis 使用(入门)

在上例的基础上,将IUserDao.xml移除
在IUserDao中加上@Select注解

import com.fox.pojo.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

//用户的持久层接口
public interface IUserDao {

    //查询所有操作
    @Select("select * from user") //指定SQL语句
    List<User> findAll();
}

在Mybatis核心配置文件SqlMapConfig.xml中修改mapper

    
    <mappers>
	
        <mapper class="com.fox.dao.IUserDao"/>
    mappers>

MyBatis学习总结(一)什么是框架什么是持久层什么是MyBatisMyBatis的优缺点(面试题)MyBatis和Hibernate的区别MyBatis使用入门_第9张图片
通过快速入门示例,我们发现使用 mybatis 是非常容易的一件事情,因为只需要编写 Dao 接口并且按照mybatis 要求编写两个配置文件,就可以实现功能。远比我们之前的 JDBC 方便多了。我们使用注解之后,更为简单,只需要编写一个 mybatis 配置文件就够了。

你可能感兴趣的:(SSM,java,mybatis)