优秀的编程知识分享平台

网站首页 > 技术文章 正文

【MyBatis系列教程一】初识MyBatis

nanyue 2024-11-21 18:55:28 技术文章 2 ℃

1.1 ORM概览

在了解ORM之前我们先了解什么是持久化,因为所有的ORM框架所做的事情无非就是将对象映射成数据库中的数据,以及将数据库中的数据映射成对象。

1.1.1 什么是持久化

所谓持久化就是把数据(内存中的对象)保存到可永久存储的存储设备中(例如:硬盘),持久化的主要应用是将内存中的数据存储在关系型数据库中。当然也可以保存在磁盘文件中,XML数据文件,JSON文件中等的。

1.1.2 什么是ORM

ORM(Object-Relational Mapping),对象关系映射,它的作用是在关系型数据库和对象之间做一个映射,这样,我们在具体的操作数据库时,就不需要和复杂的SQL语句打交道,像平时操作对象操作数据即可。
在目前的企业应用系统设计中,MVC,即 Model(模型)- View(视图)- Control(控制)为主要的系统架构模式。MVC 中的 Model 包含了复杂的业务逻辑和数据逻辑,以及数据存取机制(如 JDBC的连接、SQL生成和Statement创建、还有ResultSet结果集的读取等)等。

将这些复杂的业务逻辑和数据逻辑分离,以将系统的紧耦合关系转化为松耦合关系(即解耦合),是降低系统耦合度迫切要做的,也是持久化要做的工作。MVC 模式实现了架构上将表现层(即View)和数据处理层(即Model)分离的解耦合,而持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。

而 ORM 作为持久化设计中的最重要也最复杂的技术,也是目前业界热点技术。
简单来说,按通常的系统设计,使用 JDBC 操作数据库,业务处理逻辑和数据存取逻辑是混杂在一起的。
一般基本都是如下几个步骤:

  1. 建立数据库连接,获得 Connection 对象。
  2. 根据用户的输入组装查询 SQL 语句。
  3. 根据 SQL 语句建立 Statement 对象 或者 PreparedStatement 对象。
  4. 用 Connection 对象执行 SQL语句,获得结果集 ResultSet 对象。
  5. 然后一条一条读取结果集 ResultSet 对象中的数据。
  6. 根据读取到的数据,按特定的业务逻辑进行计算。
  7. 根据计算得到的结果再组装更新 SQL 语句。
  8. 再使用 Connection 对象执行更新 SQL 语句,以更新数据库中的数据。
  9. 最后依次关闭各个 Statement 对象和 Connection 对象。

由上可看出代码逻辑非常复杂,这还不包括某条语句执行失败的处理逻辑。其中的业务处理逻辑和数据存取逻辑完全混杂在一块。

而一个完整的系统要包含成 千上万个这样重复的而又混杂的处理过程,假如要对其中某些业务逻辑或者一些相关联的业务流程做修改,要改动的代码量将不可想象。

另一方面,假如要换数据库产品或者运行环境也可能是个不可能完成的任务。而用户的运行环境和要求却千差万别,我们不可能为每一个用户每一种运行环境设计一套一样的系统。
所以就要将一样的处理代码即业务逻辑和可能不一样的处理即数据存取逻辑分离开来,另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序 运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。

所以为解决这一困难,就出现 ORM 这一个对象和数据之间映射技术。常用的ORM框架有Hibernate、Mybatis、Mybatis-plus等,接下来我们以Mybatis为例深入学习。

2.Mybatis概览

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
下面我们先了解一下Mybatis架构:

  • mybatis-config.xml: Mybatis全局配置文件,用于配置数据库、数据库连接池、POJO别名、映射文件等信息
  • mapper.xml:该文件中用于编写处理数据的SQL语句。并且通过此文件可以将SQL语句与Java代码完全分离
  • SqlSessionFactory:用于创建Java和数据库会话的Session对象
  • Session:与数据库建立会话对象
  • Executor:真正执行Sql语句的对象
  • Statement:mapper文件对应的Statement,因为mapper文件是相互隔离的,可以理解为一个mapper文件就对应一个Statement对象。

2.1 Mybatis入门

在本小节内,将使用Mybatis框架搭建开发环境,并使用Mybatis进行单表的增删改查,其中涉及到的一些概念会在后续章节中陆续讲解。

2.1.1 新建Mybaits项目

在前面的课程中,已经学习了Maven的基础知识,使用Maven可以更好的管理和构建项目,因此使用Maven构建项目。项目结构如下:


首先准数据库:

CREATE DATABASE MYBATIS_DEMO;
USE MYBATIS_DEMO;
CREATE TABLE STUDENT(
    STUDENT_ID INT PRIMARY KEY AUTO_INCREMENT,
    STUDENT_NAME VARCHAR(20),
    STUDENT_AGE INT,
    STUDENT_GENDER CHAR(2)
);
INSERT INTO STUDENT (STUDENT_NAME, STUDENT_AGE, STUDENT_GENDER) VALUES ("张无忌",18,"男");
INSERT INTO STUDENT (STUDENT_NAME, STUDENT_AGE, STUDENT_GENDER) VALUES ("张翠山",43,"男");
INSERT INTO STUDENT (STUDENT_NAME, STUDENT_AGE, STUDENT_GENDER) VALUES ("殷素素",40,"男");
INSERT INTO STUDENT (STUDENT_NAME, STUDENT_AGE, STUDENT_GENDER) VALUES ("谢逊",50,"男");

第一步:在pom.xml中导入依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>

第二步:在resource目录下新建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>
    <!--配置数据库连接文件-->
    <properties resource="data.properties"></properties>
    <!--开启驼峰命名映射-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <environments default="development">
        <environment id="development">
            <!--配置数据库事务管理器-->
            <transactionManager type="JDBC"></transactionManager>
            <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="mapper/StudentMapper.xml"></mapper>
    </mappers>
</configuration>

第三步:创建SQL语句映射文件StudentMapper.xml

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--1.namespace和接口的全限定名一致-->
<!--2.接口方法名和xml中sql语句ID一致-->
<!--3.sql语句resultType返回值类型和方法返回值类型一致-->
<!--4.输入参数类型与方法中一致-->
<mapper namespace="cn.bytecollege.mapper.StudentMapper">
  <select id="findAll" resultType="cn.bytecollege.entity.Student">
    SELECT STUDENT_ID,STUDENT_NAME,STUDENT_AGE,STUDENT_GENDER
    FROM STUDENT
  </select>
</mapper>

第四步:在java目录下,新建包cn.bytecollege.entity,并在包中新建实体类Student

package cn.bytecollege.entity;

import java.util.Objects;

public class Student {
    private Integer studentId;
    private String studentName;
    private Integer studentAge;
    private String studentGender;

    public Integer getStudentId() {
        return studentId;
    }

    public void setStudentId(Integer studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public Integer getStudentAge() {
        return studentAge;
    }

    public void setStudentAge(Integer studentAge) {
        this.studentAge = studentAge;
    }

    public String getStudentGender() {
        return studentGender;
    }

    public void setStudentGender(String studentGender) {
        this.studentGender = studentGender;
    }
    @Override
    public String toString() {
        return "Student{" +
                "studentId=" + studentId +
                ", studentName='" + studentName + '\'' +
                ", studentAge=" + studentAge +
                ", studentGender='" + studentGender + '\'' +
                '}';
    }
}

第五步:在java目录下新建cn.bytecollege.mapper包,并在包中新建接口StudentMapper

package cn.bytecollege.mapper;
import cn.bytecollege.entity.Student;
import java.util.List;
public interface StudentMapper {
    List<Student> findAll();
}

第六步:新建测试类查询所有信息

package cn.bytecollege;

import cn.bytecollege.entity.Student;
import cn.bytecollege.mapper.StudentMapper;
import org.apache.ibatis.annotations.Mapper;
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 App 
{
    public static void main( String[] args ){
        //读取Mybatis配置文件
        InputStream is = App.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //获取SqlSession
        SqlSession session = sqlSessionFactory.openSession();
//        List<Student> list = session.selectList("cn.bytecollege.mapper.StudentMapper.findAll");
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Student> list = mapper.findAll();
        list.forEach(System.out::println);
    }
}

运行上面的程序结果如下图:


从上面的代码可以看出使用Mybatis的整个过程可以分为以下 步:

  1. 读取Mybatis全局配置文件
  2. 构建SqlSessionFactory对象
  3. 创建SqlSession对象
  4. 获取自定义Mapper
  5. 执行SQL语句
  6. 获取执行结果

2.2 Mybatis对象简介

在上面步骤中出现了SqlSessionFactory、SqlSession等对象,下面就这些对象进行简单的介绍。

  • SqlSessionFactory:每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。需要注意SqlSessionFactory是一个工厂接口而不是现实类,它的任务是创建SqlSession。
  • SqlSession:SqlSession类似于一个JDBC的Connection对象。MyBatis提供了两种模式去创建SqlSessionFactory:一种是XML配置的方式,另一种是代码的方式。为了避免硬编码以及利于项目维护,通常推荐使用第一种方式,将配置和代码进行分离。
  • Mapper(映射器):映射器是由Java接口和XML文件(或注解)共同组成的,它的作用有:定义参数类型、描述缓存、描述SQL语句、定义查询结果和POJO的映射关系。

Tags:

最近发表
标签列表